{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Chapter 6 - Linear Model Selection and Regularization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- [Lab 2: Ridge Regression](#6.6.1-Ridge-Regression)\n",
    "- [Lab 2: The Lasso](#6.6.2-The-Lasso)\n",
    "- [Lab 3: Principal Components Regression](#6.7.1-Principal-Components-Regression)\n",
    "- [Lab 3: Partial Least Squares](#6.7.2-Partial-Least-Squares)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %load ../standard_import.txt\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "import glmnet as gln\n",
    "\n",
    "from sklearn.preprocessing import scale \n",
    "from sklearn import model_selection\n",
    "from sklearn.linear_model import LinearRegression, Ridge, RidgeCV, Lasso, LassoCV\n",
    "from sklearn.decomposition import PCA\n",
    "from sklearn.cross_decomposition import PLSRegression\n",
    "from sklearn.model_selection import KFold, cross_val_score\n",
    "from sklearn.metrics import mean_squared_error\n",
    "\n",
    "%matplotlib inline\n",
    "plt.style.use('seaborn-white')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lab 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 263 entries, -Alan Ashby to -Willie Wilson\n",
      "Data columns (total 20 columns):\n",
      "AtBat        263 non-null int64\n",
      "Hits         263 non-null int64\n",
      "HmRun        263 non-null int64\n",
      "Runs         263 non-null int64\n",
      "RBI          263 non-null int64\n",
      "Walks        263 non-null int64\n",
      "Years        263 non-null int64\n",
      "CAtBat       263 non-null int64\n",
      "CHits        263 non-null int64\n",
      "CHmRun       263 non-null int64\n",
      "CRuns        263 non-null int64\n",
      "CRBI         263 non-null int64\n",
      "CWalks       263 non-null int64\n",
      "League       263 non-null object\n",
      "Division     263 non-null object\n",
      "PutOuts      263 non-null int64\n",
      "Assists      263 non-null int64\n",
      "Errors       263 non-null int64\n",
      "Salary       263 non-null float64\n",
      "NewLeague    263 non-null object\n",
      "dtypes: float64(1), int64(16), object(3)\n",
      "memory usage: 43.1+ KB\n"
     ]
    }
   ],
   "source": [
    "# In R, I exported the dataset from package 'ISLR' to a csv file.\n",
    "df = pd.read_csv('Data/Hitters.csv', index_col=0).dropna()\n",
    "df.index.name = 'Player'\n",
    "df.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>AtBat</th>\n",
       "      <th>Hits</th>\n",
       "      <th>HmRun</th>\n",
       "      <th>Runs</th>\n",
       "      <th>RBI</th>\n",
       "      <th>Walks</th>\n",
       "      <th>Years</th>\n",
       "      <th>CAtBat</th>\n",
       "      <th>CHits</th>\n",
       "      <th>CHmRun</th>\n",
       "      <th>CRuns</th>\n",
       "      <th>CRBI</th>\n",
       "      <th>CWalks</th>\n",
       "      <th>League</th>\n",
       "      <th>Division</th>\n",
       "      <th>PutOuts</th>\n",
       "      <th>Assists</th>\n",
       "      <th>Errors</th>\n",
       "      <th>Salary</th>\n",
       "      <th>NewLeague</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Player</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>-Alan Ashby</th>\n",
       "      <td>315</td>\n",
       "      <td>81</td>\n",
       "      <td>7</td>\n",
       "      <td>24</td>\n",
       "      <td>38</td>\n",
       "      <td>39</td>\n",
       "      <td>14</td>\n",
       "      <td>3449</td>\n",
       "      <td>835</td>\n",
       "      <td>69</td>\n",
       "      <td>321</td>\n",
       "      <td>414</td>\n",
       "      <td>375</td>\n",
       "      <td>N</td>\n",
       "      <td>W</td>\n",
       "      <td>632</td>\n",
       "      <td>43</td>\n",
       "      <td>10</td>\n",
       "      <td>475.0</td>\n",
       "      <td>N</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Alvin Davis</th>\n",
       "      <td>479</td>\n",
       "      <td>130</td>\n",
       "      <td>18</td>\n",
       "      <td>66</td>\n",
       "      <td>72</td>\n",
       "      <td>76</td>\n",
       "      <td>3</td>\n",
       "      <td>1624</td>\n",
       "      <td>457</td>\n",
       "      <td>63</td>\n",
       "      <td>224</td>\n",
       "      <td>266</td>\n",
       "      <td>263</td>\n",
       "      <td>A</td>\n",
       "      <td>W</td>\n",
       "      <td>880</td>\n",
       "      <td>82</td>\n",
       "      <td>14</td>\n",
       "      <td>480.0</td>\n",
       "      <td>A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Andre Dawson</th>\n",
       "      <td>496</td>\n",
       "      <td>141</td>\n",
       "      <td>20</td>\n",
       "      <td>65</td>\n",
       "      <td>78</td>\n",
       "      <td>37</td>\n",
       "      <td>11</td>\n",
       "      <td>5628</td>\n",
       "      <td>1575</td>\n",
       "      <td>225</td>\n",
       "      <td>828</td>\n",
       "      <td>838</td>\n",
       "      <td>354</td>\n",
       "      <td>N</td>\n",
       "      <td>E</td>\n",
       "      <td>200</td>\n",
       "      <td>11</td>\n",
       "      <td>3</td>\n",
       "      <td>500.0</td>\n",
       "      <td>N</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Andres Galarraga</th>\n",
       "      <td>321</td>\n",
       "      <td>87</td>\n",
       "      <td>10</td>\n",
       "      <td>39</td>\n",
       "      <td>42</td>\n",
       "      <td>30</td>\n",
       "      <td>2</td>\n",
       "      <td>396</td>\n",
       "      <td>101</td>\n",
       "      <td>12</td>\n",
       "      <td>48</td>\n",
       "      <td>46</td>\n",
       "      <td>33</td>\n",
       "      <td>N</td>\n",
       "      <td>E</td>\n",
       "      <td>805</td>\n",
       "      <td>40</td>\n",
       "      <td>4</td>\n",
       "      <td>91.5</td>\n",
       "      <td>N</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Alfredo Griffin</th>\n",
       "      <td>594</td>\n",
       "      <td>169</td>\n",
       "      <td>4</td>\n",
       "      <td>74</td>\n",
       "      <td>51</td>\n",
       "      <td>35</td>\n",
       "      <td>11</td>\n",
       "      <td>4408</td>\n",
       "      <td>1133</td>\n",
       "      <td>19</td>\n",
       "      <td>501</td>\n",
       "      <td>336</td>\n",
       "      <td>194</td>\n",
       "      <td>A</td>\n",
       "      <td>W</td>\n",
       "      <td>282</td>\n",
       "      <td>421</td>\n",
       "      <td>25</td>\n",
       "      <td>750.0</td>\n",
       "      <td>A</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   AtBat  Hits  HmRun  Runs  RBI  Walks  Years  CAtBat  CHits  \\\n",
       "Player                                                                          \n",
       "-Alan Ashby          315    81      7    24   38     39     14    3449    835   \n",
       "-Alvin Davis         479   130     18    66   72     76      3    1624    457   \n",
       "-Andre Dawson        496   141     20    65   78     37     11    5628   1575   \n",
       "-Andres Galarraga    321    87     10    39   42     30      2     396    101   \n",
       "-Alfredo Griffin     594   169      4    74   51     35     11    4408   1133   \n",
       "\n",
       "                   CHmRun  CRuns  CRBI  CWalks League Division  PutOuts  \\\n",
       "Player                                                                    \n",
       "-Alan Ashby            69    321   414     375      N        W      632   \n",
       "-Alvin Davis           63    224   266     263      A        W      880   \n",
       "-Andre Dawson         225    828   838     354      N        E      200   \n",
       "-Andres Galarraga      12     48    46      33      N        E      805   \n",
       "-Alfredo Griffin       19    501   336     194      A        W      282   \n",
       "\n",
       "                   Assists  Errors  Salary NewLeague  \n",
       "Player                                                \n",
       "-Alan Ashby             43      10   475.0         N  \n",
       "-Alvin Davis            82      14   480.0         A  \n",
       "-Andre Dawson           11       3   500.0         N  \n",
       "-Andres Galarraga       40       4    91.5         N  \n",
       "-Alfredo Griffin       421      25   750.0         A  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 263 entries, -Alan Ashby to -Willie Wilson\n",
      "Data columns (total 6 columns):\n",
      "League_A       263 non-null uint8\n",
      "League_N       263 non-null uint8\n",
      "Division_E     263 non-null uint8\n",
      "Division_W     263 non-null uint8\n",
      "NewLeague_A    263 non-null uint8\n",
      "NewLeague_N    263 non-null uint8\n",
      "dtypes: uint8(6)\n",
      "memory usage: 3.6+ KB\n",
      "                   League_A  League_N  Division_E  Division_W  NewLeague_A  \\\n",
      "Player                                                                       \n",
      "-Alan Ashby               0         1           0           1            0   \n",
      "-Alvin Davis              1         0           0           1            1   \n",
      "-Andre Dawson             0         1           1           0            0   \n",
      "-Andres Galarraga         0         1           1           0            0   \n",
      "-Alfredo Griffin          1         0           0           1            1   \n",
      "\n",
      "                   NewLeague_N  \n",
      "Player                          \n",
      "-Alan Ashby                  1  \n",
      "-Alvin Davis                 0  \n",
      "-Andre Dawson                1  \n",
      "-Andres Galarraga            1  \n",
      "-Alfredo Griffin             0  \n"
     ]
    }
   ],
   "source": [
    "dummies = pd.get_dummies(df[['League', 'Division', 'NewLeague']])\n",
    "dummies.info()\n",
    "print(dummies.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "Index: 263 entries, -Alan Ashby to -Willie Wilson\n",
      "Data columns (total 19 columns):\n",
      "AtBat          263 non-null float64\n",
      "Hits           263 non-null float64\n",
      "HmRun          263 non-null float64\n",
      "Runs           263 non-null float64\n",
      "RBI            263 non-null float64\n",
      "Walks          263 non-null float64\n",
      "Years          263 non-null float64\n",
      "CAtBat         263 non-null float64\n",
      "CHits          263 non-null float64\n",
      "CHmRun         263 non-null float64\n",
      "CRuns          263 non-null float64\n",
      "CRBI           263 non-null float64\n",
      "CWalks         263 non-null float64\n",
      "PutOuts        263 non-null float64\n",
      "Assists        263 non-null float64\n",
      "Errors         263 non-null float64\n",
      "League_N       263 non-null uint8\n",
      "Division_W     263 non-null uint8\n",
      "NewLeague_N    263 non-null uint8\n",
      "dtypes: float64(16), uint8(3)\n",
      "memory usage: 35.7+ KB\n"
     ]
    }
   ],
   "source": [
    "y = df.Salary\n",
    "\n",
    "# Drop the column with the independent variable (Salary), and columns for which we created dummy variables\n",
    "X_ = df.drop(['Salary', 'League', 'Division', 'NewLeague'], axis=1).astype('float64')\n",
    "# Define the feature set X.\n",
    "X = pd.concat([X_, dummies[['League_N', 'Division_W', 'NewLeague_N']]], axis=1)\n",
    "X.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>AtBat</th>\n",
       "      <th>Hits</th>\n",
       "      <th>HmRun</th>\n",
       "      <th>Runs</th>\n",
       "      <th>RBI</th>\n",
       "      <th>Walks</th>\n",
       "      <th>Years</th>\n",
       "      <th>CAtBat</th>\n",
       "      <th>CHits</th>\n",
       "      <th>CHmRun</th>\n",
       "      <th>CRuns</th>\n",
       "      <th>CRBI</th>\n",
       "      <th>CWalks</th>\n",
       "      <th>PutOuts</th>\n",
       "      <th>Assists</th>\n",
       "      <th>Errors</th>\n",
       "      <th>League_N</th>\n",
       "      <th>Division_W</th>\n",
       "      <th>NewLeague_N</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Player</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>-Alan Ashby</th>\n",
       "      <td>315.0</td>\n",
       "      <td>81.0</td>\n",
       "      <td>7.0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>38.0</td>\n",
       "      <td>39.0</td>\n",
       "      <td>14.0</td>\n",
       "      <td>3449.0</td>\n",
       "      <td>835.0</td>\n",
       "      <td>69.0</td>\n",
       "      <td>321.0</td>\n",
       "      <td>414.0</td>\n",
       "      <td>375.0</td>\n",
       "      <td>632.0</td>\n",
       "      <td>43.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Alvin Davis</th>\n",
       "      <td>479.0</td>\n",
       "      <td>130.0</td>\n",
       "      <td>18.0</td>\n",
       "      <td>66.0</td>\n",
       "      <td>72.0</td>\n",
       "      <td>76.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1624.0</td>\n",
       "      <td>457.0</td>\n",
       "      <td>63.0</td>\n",
       "      <td>224.0</td>\n",
       "      <td>266.0</td>\n",
       "      <td>263.0</td>\n",
       "      <td>880.0</td>\n",
       "      <td>82.0</td>\n",
       "      <td>14.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Andre Dawson</th>\n",
       "      <td>496.0</td>\n",
       "      <td>141.0</td>\n",
       "      <td>20.0</td>\n",
       "      <td>65.0</td>\n",
       "      <td>78.0</td>\n",
       "      <td>37.0</td>\n",
       "      <td>11.0</td>\n",
       "      <td>5628.0</td>\n",
       "      <td>1575.0</td>\n",
       "      <td>225.0</td>\n",
       "      <td>828.0</td>\n",
       "      <td>838.0</td>\n",
       "      <td>354.0</td>\n",
       "      <td>200.0</td>\n",
       "      <td>11.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Andres Galarraga</th>\n",
       "      <td>321.0</td>\n",
       "      <td>87.0</td>\n",
       "      <td>10.0</td>\n",
       "      <td>39.0</td>\n",
       "      <td>42.0</td>\n",
       "      <td>30.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>396.0</td>\n",
       "      <td>101.0</td>\n",
       "      <td>12.0</td>\n",
       "      <td>48.0</td>\n",
       "      <td>46.0</td>\n",
       "      <td>33.0</td>\n",
       "      <td>805.0</td>\n",
       "      <td>40.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>-Alfredo Griffin</th>\n",
       "      <td>594.0</td>\n",
       "      <td>169.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>74.0</td>\n",
       "      <td>51.0</td>\n",
       "      <td>35.0</td>\n",
       "      <td>11.0</td>\n",
       "      <td>4408.0</td>\n",
       "      <td>1133.0</td>\n",
       "      <td>19.0</td>\n",
       "      <td>501.0</td>\n",
       "      <td>336.0</td>\n",
       "      <td>194.0</td>\n",
       "      <td>282.0</td>\n",
       "      <td>421.0</td>\n",
       "      <td>25.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   AtBat   Hits  HmRun  Runs   RBI  Walks  Years  CAtBat  \\\n",
       "Player                                                                     \n",
       "-Alan Ashby        315.0   81.0    7.0  24.0  38.0   39.0   14.0  3449.0   \n",
       "-Alvin Davis       479.0  130.0   18.0  66.0  72.0   76.0    3.0  1624.0   \n",
       "-Andre Dawson      496.0  141.0   20.0  65.0  78.0   37.0   11.0  5628.0   \n",
       "-Andres Galarraga  321.0   87.0   10.0  39.0  42.0   30.0    2.0   396.0   \n",
       "-Alfredo Griffin   594.0  169.0    4.0  74.0  51.0   35.0   11.0  4408.0   \n",
       "\n",
       "                    CHits  CHmRun  CRuns   CRBI  CWalks  PutOuts  Assists  \\\n",
       "Player                                                                      \n",
       "-Alan Ashby         835.0    69.0  321.0  414.0   375.0    632.0     43.0   \n",
       "-Alvin Davis        457.0    63.0  224.0  266.0   263.0    880.0     82.0   \n",
       "-Andre Dawson      1575.0   225.0  828.0  838.0   354.0    200.0     11.0   \n",
       "-Andres Galarraga   101.0    12.0   48.0   46.0    33.0    805.0     40.0   \n",
       "-Alfredo Griffin   1133.0    19.0  501.0  336.0   194.0    282.0    421.0   \n",
       "\n",
       "                   Errors  League_N  Division_W  NewLeague_N  \n",
       "Player                                                        \n",
       "-Alan Ashby          10.0         1           1            1  \n",
       "-Alvin Davis         14.0         0           1            0  \n",
       "-Andre Dawson         3.0         1           0            1  \n",
       "-Andres Galarraga     4.0         1           0            1  \n",
       "-Alfredo Griffin     25.0         0           1            0  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### I executed the R code and downloaded the exact same training/test sets used in the book."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = pd.read_csv('Data/Hitters_X_train.csv', index_col=0)\n",
    "y_train = pd.read_csv('Data/Hitters_y_train.csv', index_col=0)\n",
    "X_test = pd.read_csv('Data/Hitters_X_test.csv', index_col=0)\n",
    "y_test = pd.read_csv('Data/Hitters_y_test.csv', index_col=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.6.1 Ridge Regression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scikit-learn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The __glmnet__ algorithms in R optimize the objective function using cyclical coordinate descent, while scikit-learn Ridge regression uses linear least squares with L2 regularization. They are rather different implementations, but the general principles are the same.\n",
    "\n",
    "The __glmnet() function in R__ optimizes:\n",
    "### $$ \\frac{1}{N}|| X\\beta-y||^2_2+\\lambda\\bigg(\\frac{1}{2}(1−\\alpha)||\\beta||^2_2 \\ +\\ \\alpha||\\beta||_1\\bigg) $$\n",
    "(See R documentation and https://cran.r-project.org/web/packages/glmnet/vignettes/glmnet_beta.pdf)<BR>\n",
    "The function supports L1 and L2 regularization. For just Ridge regression we need to use $\\alpha = 0 $. This reduces the above cost function to\n",
    "### $$ \\frac{1}{N}|| X\\beta-y||^2_2+\\frac{1}{2}\\lambda ||\\beta||^2_2 $$\n",
    "The __sklearn Ridge()__ function optimizes:\n",
    "### $$ ||X\\beta - y||^2_2 + \\alpha ||\\beta||^2_2 $$\n",
    "which is equivalent to optimizing\n",
    "### $$ \\frac{1}{N}||X\\beta - y||^2_2 + \\frac{\\alpha}{N} ||\\beta||^2_2 $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYQAAAEWCAYAAABmE+CbAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XecHVXd+PHPzNy+d+/e7SXZ9OSkQUJC6L33qiJFFLGL7Xksj+0RxUd91B+KnUdFBJQiAoK00AklJEBIQhJOejbJ9r633ym/P2Y2WcKmka3Jeb9ed+feuVPOzM6d78w5Z87RHMdBURRFUfThToCiKIoyMqiAoCiKogAqICiKoigeFRAURVEUQAUERVEUxaMCgqIoigKAb7gTMBoJIRzgbcACHCACdAOflVK+LoT4DBCXUv6kn3kTwGwp5eYhTPI+EUJ8G/g08DTwK+CfQCfwV2CKlPKLe5j3T8A9Usqn3+e6zweOllL+9/uZfzAJIT4G/ABYI6U8e4CXvRC4SkrZKoR4DPiqlHL1QK6jn3V+jN1szy7p2Qx8QEr5+mCm50B4v8VyKWXrfszzvo9VIcRE4OdSysuFEDXA/VLK4/Z3OSOVCgjv36l9D0IhxFeBXwPHSin/MHzJOiDX454MXhJC/DfwnJTyE/sy475OtwcLgJIDXMZguRb4lpTyrkFY9pm9b6SU5w3C8vuzp+05s59xB5UDPFbHA8JbTj1w0AQDUAFhQAghfMA4oN37fCNQJqW8QQhxIm6gcICl9MmmE0L8F+5JuAd4EbhESjlBCBEA/hc4GTCAZcAXpZTd/az3p8AFgAm8AnzOW9fNwOm4dzGvAV+RUvYIIcYAv/HS68e9UvqREOJeYCzwZyHEj7zlGEKIMPAU7pXiBUKIKuAPwHTABv4gpfyVEOJ54DdSyvuFEMd56S/w1v99KeW/vSvTS735pgIp4KNADPiMt74ub3/dAZR5m/qolPK7/ez3j+Pe0QRwg8lPpJS/99L4vuffZZpfAEcBE4UQ5cAc4G0p5c+972/v/exdUd/u7fdxwB296/XW9Z/e/mj1tvsH3mqeE0KcByzy9vPrQohPAV/0pm8CbpBSrvXW1w0cBtQCK4BrpZSJXdJdBPwWmIt7PDwOfAv4Wd/tkVL+os88f9klPQCfFkL8AagA7pRSftub9kLgO96+S+He2by6SxomeNu0BpiAezxPpP9jw/DSdhHQhXvMzpRSntL32PKW+67P3rgC4Pe4x1Up7m/qKiml9KZvxz1mfw9cjvsbsIDv9UnyFOBBKeVHhBDfAi4Gwl5avwo8DPwJGCOEeBL32HlbShkVQvjZ/W9uM7s5LkYaVYbw/j0nhFghhKgH1nrjrus7gXdi/wfwn1LKI4DncA8whBBnAx/DvTKeDxT2mfW/cE/w86WUc4B64D3ZT7gn7fm4J6nZ3jKuwP2h1njj5+D+n3/mzXMncJuUcj7uieEMIcSHpJRXeOu5Wkr5V9yT/r1Syqt3WefvgLVSyunAscCnhBBT+mxzMfAX4CNSynm4P6rfCyHGeZOcDHxBSjkb90fzX1LK1/qs79vAJ4GN3vwnAlO9E1zffRv1pjvP27dX4AZHBmD+HaSUXwFeB77W9+S5B1Ep5Ym4V45fFUJMFELMwT0JniOlPBz3xPJtKWXv8XKqlHJrn7SdBnzdGz8H+DvwkBBC8yaZD5wDzMA90X6wn3T8CmjDDRxH4h4HX93T9uwmPRkp5ZG4x8p/CiFqhRBTgR+xc999CnjAOynvaixwk5RyGpBh98fGJ7ztmo17XE3ud+/u3rlAp5TyWG9dS4Eb+nzfIaWcKaX8dZ/tfVBKOVdKORf4LtCI+z8bD5wBnOL9v74N/EBKaXnp3NBP1uGefnPQz3Gxn9s3JNQdwvt3qpfPOg94DDd7pXmXaQ4D8lLKZwCklHcLIW71vjsP+IeUshNACPFb3CsIcK/448CZQghwr8J2XTa4B+2dUsq09/kKb1lLcE84ee/zr3FPKAW4J+QSIcRN3jxR3KvI+/Zxu8/APVkhpezC/QHjpRPcH3O1t77ecQ5wuPf+DSnlNu/9m8Bl/azjCeAx70TxNG7Q6Oo7gZQyIYS4ADjfO0HN9bZlIOY/EP/ylr9dCNGMe+dxMvBk70lWSvnLvSzjHNzg2OJNf7sQ4hbckz/AE1LKLIAQYiX9Z7WdCxwvpXSArHeV/2X6v7DYk797aWgUQjTh3ikcjfs/fqbP/9jGvcJevsv8JtB757CnY+M83CvnjLddt+LeIe0T7850oxDiC146TumzXnDvVPolhDgG987hTCllkzfuWuBq72LnGPZ+bJxLP7+5Pt/3d1xs2tftGyrqDuEASSnfBL4C3O7dIu9K2+Wz2WfY9zurz3sD+FKfq5ejgA/0s2wT9wcFgBCiUghR7c3ft5EqHTd7yPDWeVyfZR+De7W3r3Zd5yQhRGyXtK/pXX6fdTzpfZ/uM63De/cPUsqluFkL/4d7ElwihJjfdxohxFjgLdw83Zdwr9AGZP692DXNgV2+72/7dt1nYSHE9D2sY9f/H95y/HtYx650+j8G9le+n3UZwDP9/I/f7mf+rJSy95jf07Gxp9/D3vY5QojPAn/Gzb76O3D3LvMkdp3Hm28abuWJa6SUa7xx83CDSQxYiHt3198+7mt3v7le+/I/G3YqIAwAKeXdwBJg1yyFFYDWmx8rhLgIKPa+exS4vE9WxvXsPKCeBG4QQgSEEDrwR+DH/az6aeAqIUTQm+73wJW4V8ifFUL4vfGfB57yyiAWA//hpScOvIx7676vnsbLGvPS/gxuvm2vxbhZNCd508wF1gFj9rJcE+8HJIT4CfBdKeVDwJeAVXh3In0cCbQAP8T90V7gzWsc6Px7SWeLNy/CrWVy8l6mBzer8AwvWIOb99ybPWXx3hP1E8CHvTILhBDX4Wb/rN+HdfXqPYY0IUQQN1vnqX2Yr7/07OoZ4KzeoOYd3yvwskP3YE/HxqPANd6x7MPNTu39PfTd5zPZebfZ19nA7VLKPwMSuBD3JL1bXlnT47jZZ8/3+eok4HUp5c3AC8AlfZa14zjdRb+/uT2tfyRSAWHg3ACc55UNAODdPl4C3CSEeAs3e6TZ++5Z3BP9q0KI14Ei3KsbgJuAzbiFyatxryb+s5913gq84b1WAg24ecc/xM0PfQu3QM+Pe2IEuAo4xstqeA24W0r5t/3czhlCiBW4weTHUso3+mxzC26h3c+EEMtxyyw+IvdezfZZ4GzvVvuXwFwhxNu4+d2bgHt2mX4hsA33x78Gt7CuBTe74EDn35NfA9VCCImbH/7sXqZHSrkS+BrwhLdPzsEtRAe3jOkFIcTsPtM/hXtx8awQYhVuAfQFUkp7b+vq44u42TsrvZcE/mcf5ntPevrZntW4AeYeb3tuAi7atWC7n/n2dGzcjns8LsOtHJFj5+/hh7gB6G3cgvgX+1n8z3ELwFfgZg+9yd7/l9/H3UdfFkK85b0ew727KBNCrMH9/SVws1kLvc8ZL1u271X+nn5zo4ammr8eHkKII3Gzbn7lff4P3Hr4VwxvyhRl6AkhzgIqpFcV1iszyUgpvzG8KTu0qELl4bMW+IZwqxc6QB3uVZeiHIpWAV8TQnwdN3tmOfDZ4U3SoUfdISiKoiiAKkNQFEVRPCogKIqiKMAoLUPwqtEtwK1VY+1lckVRFMVl4D4cuLT34ca+RmVAwA0Gu33yUFEURdmjE3EfyHyX0RoQGgD+9re/UVVVNdxpURRFGRUaGxu5+uqrwTuH7mq0BgQLoKqqirFjxw53WhRFUUabfrPaVaGyoiiKAqiAoCiKonhUQFAURVEAFRAURVEUjwoIiqIoCqACgqIoyqjgOA6ZvEVPJr/3id+n0VrtVFEUZdTK5C2aujPUd2Zo6s7QmsjSlszRnsjRlc7Tlc7TncmTzJokshapnEk6b9HbFukvrpjDpUcMfJV7FRAURVEGSXcmzzsNPayu70I29bCpNcnm1hSN3Zn3TOvTNUoKAsQjforCfqpiIaIhH5GAj4KAQSRgEAoYFAR8nDKtYlDSqwKCoijKAGlNZHl5fSuvbWpn6aZ21jXv7ESuOOJnYlkBx00pZUJpATXxMNVFIaqKQpRFg8RCPjRteLtaVgFBURTlAGxtT/HoygaeWt3Em3UdOA4UBn0cOaGYi+fWMGtMEbOqY5QXBof9hL83KiAoiqLsp5xp89TqJu5ZWseida0AzKqJ8aXTp3L69Epm1sQw9JF98u+PCgiKoij7KJO3uHfpVn7//AYauzOMiYf5yhnTuHz+GMYWR4Y7eQdMBQRFUZS9sGyHvy+p49fPrKO5J8uCCcX8+LLDOGla+ai8E9gdFRAURVH24O3tXXzrwZWs2NbFURNK+OWH53LspNIRXx7wfqiAoCiK0o+safGzJyS3vbyJkoIgv7ryCC48vPqgDAS9VEBQFEXZxdb2FDf8/U2Wb+vi6qPH8fVzplMU9g93sgadCgiKoih9PPtOE1+5dzm27fCHa+Zxzuzq4U7SkFEBQVEUxfO317bwnYfeZkZVjN9dPY8JZQXDnaQhpQKCoiiHPMdx+N3zG/jZk5JTRTm/u3o+4YAx3MkaciogKIpySHMchx89toY/LtrEJXNr+NkH5+A3Ds2GoFVAUBTlkPbLp9fxx0Wb+Oix4/nehbPQD6LnCvaXCgiKohyy7ly8hVueWccH54/lxotmHdRVSvfFkAcEIUQF8AZwJmACtwMO8DbweSmlLYT4HnC+9/2XpZRLhjqdiqIc3B5b2cB//+ttTp9ewY8vO+yQDwYwxD2mCSH8wK1A2ht1M/AdKeWJgAZcLISYB5wMHA18GPjtUKZRUZSD3/KtnXz5nreYN66Y31w1D98hWmawq6HeCz8H/gDUe5/nAy947x8HzgBOABZKKR0pZR3gE0KUD3E6FUU5SLUnc3zub29SXhjkT9ceeUjWJtqdIQsIQoiPAS1Syif7jNaklF6ncPQARUAM6OozTe94RVGUA2LZDl++9y1aerL8/pp5FBcEhjtJI8pQliF8HHCEEGcAc4E7gL79wBUCnUC3937X8YqiKAfk18+u48W1Lfzo0sM4fGx8uJMz4gzZHYKU8iQp5clSylOAt4BrgceFEKd4k5wLLAJeBs4WQuhCiHGALqVsHap0KopycFq8sY1bnlnH5fPGcuVRtcOdnBFpuKud/ifwRyFEAFgD3C+ltIQQi4BXcQPW54czgYqijH7JrMnX7l/O+JIIN12iqpfuzrAEBO8uodfJ/Xx/I3DjECVHUZSD3I8fX8O2jjT3ffpYIoHhvg4euVRdK0VRDmovrWvlrsV1XH/8RBZMKBnu5IxoKiAoinLQ6snk+fr9y5lUXsBXzxbDnZwRT907KYpy0Prl0+to6M5w/2eOI+RXzxvsjbpDUBTloPROYze3v7KZDy8Yx/zxxcOdnFFBBQRFUQ46juPw3/9aRWHIx9dVVtE+UwFBUZSDzsPL61myqZ2vnz1dPY28H1RAUBTloNKTyfM/j67h8LFFXLFAPYC2P1ShsqIoB5U/vLCB5p4s/3ftkRiHcGc374cKCIqiHDQautL8adEmLp5bw9zaIWiryMpDusN9Zbog0w3Zbsgl3Vc+CfkM5FNgZsHKesOcO6+Vd9/bJtiWNzTBscCxwbZ3vu99aTqc93OYfOqAb44KCIqiHDR+8dRaHAe+etYAFCRbeWjfBB2boXMLdNZB93boaYJEIyRb3CCwL3xh8IfACIIv4A6NABh+96X7QTfc73QfaIZ74te9Ye97NPf7aOWBb19/yRyUpSqKogyxdxq7uf+NbXz8+InUlkT2b+Z0J9Qvg4a33GHzGmjf6F6t9zKCEKuBwmqoOgwKyiFSBpESCBdDqMh9BQshUACBKPgj4AvCKGk7SQUERVEOCv/7+DtEgz5uOG3K3ifOZ2DTi7DpBXfYuBK3J1+geAJUzobp50OZgNLJEB8HBRWgH9z1cFRAUBRl1HtlQyvPyRa+dd504pHdVDM1c7D2cVj9L1i7EHI97lV/7VFwyjfdYfUc94r/EKUCgqIoo5rjOPy/hWupioW49tgJ752gYzO8cTu8eSekWt1sntmXwYyLYMIJbt6+AqiAoCjKKPf82hbe2NLB/1w6+93tFbVtgBd+Civvcz9POxeO/LhbO0dX7Rr1RwUERVFGLcdxuHnhWsYWh/ngfO8htEQzPHsTLPubW5Pn2M/D0Z+BorHDm9hRQAUERVFGrYWrm1i5vYuffuBwAoYGy+6CJ7/t1vs/6pNwwn9A4eBU0TwYqYCgKMqoZNsOv3hqLRPLCrhsMnDnJbDxeRh3HFz0KyibOtxJHHVUQFAUZVR67O0G3mns4ZbTwvj+eAqYGTj/Zph/3UFfPXSwqICgKMqoY9sOv3pmHVOiOS545VoomwRX/A3Kpw130kY1FRAURRl1nlhZz9qmBLf4b8WYfS5c8nv3CWHlgKiAoCjKqGLn8/zqoReYrCW44KRj4IzvjZqmIUY6ldGmKMroYeZYeNt/8066iC8c7mCceaMKBgNIBQRFUUYH28Z+4FPcsnksEwvyXPChTw53ig46KiAoijI6PPVdnl5ZxxpnAjecdyQ+Q52+BpoqQ1AUZeR79Xc4r/yGXwVvZXxhhIvn1gx3ioaO47id6pgZrzMdC2LVg7IqFRAURRnZ1jwCT36L52o+xdubCvnpB6aMzruDbAJ6GrxXIyRb3cb2Uu1eb2tdbm9r2YTX41oC8mk3EPQ2zd3r4t/CEdcMeBJVQFAUZeRqWQsPfganZj635C5ibHGeS48YM9yp2j3bhs7N0LQamldDi3RbW+3YBKm2906vGW7nOuG417lODAqr3M51AgXgD+/sbc0Xcttm8kdgxoWDknwVEBRFGZlySbjvWvAFeXHBb1h+70Z+fNlh+EfS3YGZg62vwZaXYesS2P76u7vVLBoHJRPdE3h8PMTGuNk90SooKINQfEQ9Va0CgqIoI4/jwCNfhpZ3cK55gFsWtlNTFOLyeSOgxdJ0h5uNJZ9we1zLJQANKmbCzEtgzHyonAXl0yEYHe7U7hcVEBRFGXlev83tx+DU7/Cyczhv1r3GTZfMJuAbpqtpy3R7W1t+D6xb6BbuFo2Dwz4IU86AiSe6WT6jnAoIiqKMLC1r4clvweTTcU74D27542tUxoJ86MhhuDtItcObd8DSP0HXVjerZ8En4bDLoWbeQfdQnAoIiqKMHFYeHvyUW3B6ye94eWMHSzd38IOLZxH0DWEvZ5kuePW38Orv3L6XJ5wI5/wExLkHdW9rKiAoijJyvPgzqF8GH7oDJ1rJL55+leqiEFcsqB2a9Zs5eO0P8NLNblnBjIvg5G9A1eyhWf8wUwFBUZSRYetSePHnMOdKmHkxi7y+km+6ZPbQ3B1seQX+/RVoecctFzjtu1Azd/DXO4KogKAoyvDLZ+Chz0CsBs79XxzH4RdPr6WmKDT4ZQeZbrfMYtmdbkHxlfe4WUOHIBUQFEUZfi/8BNrWw0cehFARL65tYVldJ/9z6SDfHWxdCv+83i0wPv5LbvZQoGDw1jfCDVlAEEL4gduACUAQ+CGwGrgd97nst4HPSyltIcT3gPMBE/iylHLJUKVTUZQhVv8WvPwrmHsNTD4Nx3G4eaFkTDzMB+cPUtmBbcOi/wfP/9h9WOy6x2HcMYOzrlFkKCv1XgO0SSlPBM4FfgPcDHzHG6cBFwsh5gEnA0cDHwZ+O4RpVBRlKFl5ePgG96nds38IwBNvN7J8WxdfPmPq4Dx3kOmGe66C534Isy6BzyxSwcAzlFlG/wDu7/PZBOYDL3ifHwfOAiSwUErpAHVCCJ8QolxK2TKEaVUUZSi8fAs0rnT7Qw4XY1o2P1somVoR5bLBeCq5dZ0bDNo3wnk/hwWfOOieJTgQQxYQpJQJACFEIW5g+A7wc+/ED9ADFAExoG8rUL3jVUBQlINJ63p44acw82KYcQEA/3xzGxtbktz6kfkY+gCfqDc+D/deC4YPrv0XTDhhYJd/EBjS58CFELXAc8CdUsq/A3afrwuBTqDbe7/reEVRDhaOA498yW3F89yfAZDJW/zy6XXMrY1z1szKgV3f8nvgrg9A0Rj41PMqGOzGkAUEIUQlsBD4hpTyNm/0MiHEKd77c4FFwMvA2UIIXQgxDtCllK1DlU5FUYbAsjthy0tw5k1Q6J7873x1Cw1dGb5xznS0gcrGcRz32YYHP+2WE1z3OMTHDcyyD0JDWYbwLaAY+K4Q4rveuC8BvxJCBIA1wP1SSksIsQh4FTdgfX4I06goymBLNMPC78D44+GIjwDQnszx62fXcdK0co6dXDow67FteOIbsOT/4LAPuZ3K+AIDs+yD1FCWIXwJNwDs6uR+pr0RuHGQk6QoynB4/BtuT2AX/HJHXwA3PyVJ5iy+e/6MgVmHlYeHPue2mHrsDe6dyAjqd2CkUg+mKYoydOQTsOoBOOVbUD4NgHcau/n7a3Vce+wEplYW7mUB+yCfhvs+CuuehNO/Byd8RdUk2kcqICiKMjQy3fDof7gdyZzwFQAcx+EHj6wmFvbz5TOmDsA6uuDvH4a6V+GCX8CRHz/wZR5CVEBQFGVoPPMD6K6HD92xIy9/4eomXtnQxg8unkU8coD5+8lWuOsyaFoFH/gzzL58ABJ9aFEBQVGUwVe32O1k5ujPwNgjAUjlTH746GqmVUa56qgDrPnTtQ3uvBQ6t7qN0009cwASfehRAUFRlMGVz8DDX4CiWjjtOztG/+KptWxtT3Pvp47BZxxAgW/zGrjrcsj2wEcegPHHDUCiD00qICiKMrie+yG0roVrHtjR6fyKbZ38+aVNXHX0OI6edADVTOsWw98/BL4wXPcYVB02QIk+NKl6WIqiDJ4tr8Irv3ELd6ecDkDesvnGP1dSFg3yX+dOf//LXv0vuONiKCiH6xeqYDAAVEBQFGVw5JLw0GfdJ4PPvGnH6D8u2siahm5uumQ2sZB//5frOPD8/8J910LV4fDxhVA8fgATfuhSWUaKogyOp74HHZvgY4/uyCpaVd/FL59axzmzqjh7VtX+LzOXgn99DlY96Ha1eeEt4AsOcMIPXSogKIoy8NY+CUv/CEd/dkdDcqmcyRfuXkY84ud/Ln0fndY3r4F/XOf2eXzmTXDcFwbkgTPLzJNNJsmmkuTSaXKZNPlshnwmi5nrfeUx8zmsfB7LzGOZJrZpYlsmlmnh2Ba2ZWHbNk7v0LFxbPflfnbAsXEccBwbvKHjAI6D445wE+Xgfsb7rrdNaBw0Xefkaz7O2BnvYx/uhQoIiqIMrK7t8OBnoPIwOOPGHaO///BqNrUm+dv1R1Ma3Y+reseBN/4CT3wTgoVwzT9xJp+Kbaex7Ty6HkLXA+9pEC+XTtHZ1EhXcyM9bW0kOtpItLeR6uok3d1NqqeLTKIHM5vdr83TDQPD50f3GeiGD8Mw0AwDw/ChGQa6rqP1vjTN/azpoGtomjtux0v3eTFNA29cL03TdgQ8dxJtx/r9wdB+pXlfqYCgKMrAsUz45yfAzMIH/+I2bw08sryee1/fyudPncxxU8r2aVG2nSWx/Tn8C39AeOsqusvLkTOrSGz7InZdZpepNTQniJ2PkE/6SbU5JJsh3R4k0x7CTPvQDR/RkhIiRXGiJSWUj59IKBolVBAlGI0SDEfwh8MEQu7LHwziCwTxBYP4/AGMgB+fz492ELeJpAKCoigD54WfQN0rcOn/QZnbFMW6ph6++cBK5o2L8+Uzpu1x9lRqC62tT9PS/BSx1S8zcXM3GrBhajnt0w4nHK4lqpeQaO+hu6mdrqYWUt1taIaFEbAIFtmE4zmKJmSJT0ntWG4gUEW8aD7x+DzixccQLZjmXrUr76ICgqIoA0M+4fY9MPcamHMFAG2JLB//61LCAYPfXDUPfz8PoOXznTQ2/ov6hvtJ9KyivC3HjDqTSCJNdvw8nPN+RlGunNbXX2PFG6/RsP51cBx8gSA10w5jwtTpVE6eStWkqURLSndku+RybSSSa0n0rKGrexldXW/S3PIoAH5/CcXFx1BSfBwlJScRDo8Zuv00gqmAoCjKgWtaBf+8HqrnwHluD2hZ0+LTd75Bc3eWez99LDXx8Ltm6Um8Q13dH2lufgzbyjImW8PcTQUEW9qgdCrJ47/Eyu0+1vzkT7TXbwOgavJUjr38SsbNPpyqKQKff/fVVgOBUkoCx1JSfOyOcZlMPR0di+noeJX2jldobn4MgEhkEiUlJ1JaehLF8aMxjPDuFntQUwFBUZQDk2hxWxgNROHKuyEQwXEcvvnASl7f0sFvrjqCubXxHZN3dCxhy5bf09b+Ij4tjMjNoXL9eoyWlTiFNdTPuIFFq3Ns++W9AIydOZt5513E5PlHEy05sM5zQqEaqqsvo7r6MhzHIZlaT3v7S7S1vUB9/T1s2/ZXdD1AvGgBxSXHU1J8HIWFsw6Z7KW9BgQhRDVuT2cm8A3g11LKtwY7YYqijAL5DNx7NSSb3e4pYzU4jsOND6/igTe385UzpnHB4TUAdHevYMOG/0d7x0tEnBhHJOdRvP5ttO7HsYons7bywzz7RifJJcuJV1ZzwpUfZcYJJxMrqxiUpGuaRrRgKtGCqYyrvQ7LytDZuZS29hfpaH+ZDRt+ygbA54sRjy9wX0VHUlg4E10/OJ992Jc7hDuAH+F2ZXk/8Avg1MFMlKIoo4CZg/s+AluXuDWKxsxz+zf492r++uoWPnniRL54+hRSqU2s3/BTWpqfpDQV4ZjO8UQ2r0SzNpKrPpqVzom8+FoTjt3A5COPZs5Z5zF+9pwhr81jGCFKS0+ktPREALLZFjo6XnGzmDqX0Nr6DACaFqCwcAaxwsOJFs6gMDqDgoKpB0U2074EBB/wIvBtKeU9QojPDXKaFEUZ6aw83H8drFvodoU561Icx+FHj63hLy9v5rrjJ/C1M6tZt+6HNGy5g+oWkxNaAgQ7tkKgk+Tki3m1roDlz27AH2xnzlnnMe/ci4lXvo+nlwdJMFhOVdXFVFVdDEA220xX1zK6u9+iq2sZDY0PYG1PelNrhEI1RCKTiEQmEg7VEgqPIRwaSyBYScBfMiqynfYlIASAm4EXhRCn7uNYrNjOAAAgAElEQVQ8iqIcrCwTHvw0vPNvOPencOR1ZE2Lbz6wkgfe3M61x9Ry3ZylLH/m51RtbeWEZhPDzEPV4XQs+BjPL+tk479WEYoWctyHruaIsy8kFI0O91btVTBYQUXF2VRUnA24Txmn01tJJNaQSK4jldpAKrWRhoY3sazku+bVNB+BQBl+fwkBfwn+QDE+XxF+XyE+XwzDF8UwIviMAnQjjKGHMIwwuh50H7rTA+haAF33o+uBQcuy2peT+8eAM4E/AxcDVw9KShRFGflySbj/47D2Cbf5iKM/TWcqx6fufIMlm9r57HEGFznXE31gE+M68ziGH23W5TRXnsGLzy1ny3MvEymKc9LV1zHnrPMIhEZvNoum6UQi44lExlPBOTvGO46DaXaSTm8jk6knm2smm20il20mn+8gl28n3V2HafZgmt04jrW/a2b2rFuorDx/YDeIfQsIX5JS3uC9v08IcQdw7YCnRFGUka2nye17oHEFnH8zLLiedxq7+dxdb9LR0cpfJ9/BUasXEc7YWNFSnNM+T1P8OF565DG23PtXIkVxTr7m48w58zz8ocFpemFvnJ2NAg0qny9OYWGcwsI9tzfkOA6WlcSyUlhWEtNMYNtZLCvtNc2Rcz/bWRzHxLHzOI5FPL5gcNK9uy+EEJ8HvgOUCCEuw2tOA1g9KClRFGXkalgB91wNqVb48N04087mjlc2c/tjL3C971E+GHya4HaLTMUE7Au+S5NP8Oo/76P+je9TGI5wyvGnM3n6bLRslsRDD2Enk9jJFHYqhZ1O42Qy2JkMTiaDk89hZ3M4+TxOzhuaecibOKaJY1lgWTi27Q4dBywLbNttDs628VqQgyEKAENK18n+YiLBs88a8EXvNiBIKX8L/FYI8S0p5Y8GfM2Koox8jgOv3QpPfRfCJfCxR2ksmMFffnMr89ffw0PpNZgJnWbfWCiYS2plktTtP0VPJplp2czsXc4ba2joZ/FaOIweiaAHg2jhMFowgB4MoQWD6JEIWiCA5vejGQaazwd+H5rhQzN0MHxouga64TYcp+ug6W4jcBp9GovT3t0q6gC0kDqcNEMnPHfOoCx7X7KM7hZCfBWI9I6QUv5gUFKjKMrIkWjBeegGcm88TSYwj5R9DI2f+S+C9du4JGkDGvWUuNP6HLLBt0niYIZDFM8+ipI5c/GXl2MUFWEUxTFihejRQvRoAUY0ihYKHdQNxY1G+xIQ/g48ATQOcloURRlmVlcXqddfJ/3YX0m9vphMq45jVQDbwPgHRYUmVqlO7shCYsddRmsqxtsr3qC5rYWiqmrmn38Js089E3/g4Hxw62C3LwEhJaX8/qCnRFGUIeeYJully0gseonkq6+SWfU22A7oDqHyAIHDIhSHthKK51kWm0zH1HGIuZfR8FobzzzzPPlshuopgguuvZ6pRx2Hbhjuch2H1rxJUzZPU86kOZenM2/RbVr0WBY528F2wMLBr2lEDYOoT6fM76M2FGBcOEBtKEBA3UEMqT0VKve2U9skhLgSeBPcMhsp5dohSJuiKIPATiZJvPACPc88S2LRIuzubtB1wjUBymZ04xvjxyg2iWndtDmFPKwdS37aWEThGFqe38w7//4bPn8AcdxJjDvjPNrLq3k1leWujQ1sSGXZmsmxLZMjbb+3QFcDooZOUNfRNTA0jaxtk7RssrtMH9A0ZkXDzItFWFBUwKklhRT5h+YxKMd2sCwb2/SGloNl2ji2g2ODbTk4joNtOzvGOV7PZo5XmL2jTLu3x7PeXtAc70S6o0O0fgq+nR1fv4emQe30Egz/wAfLPe3dW/u8/1Sf9w5w2oCnRFGUQWMnk/Q8+xzdTz5BctFLONksRkkxhfMmEY2sJxjaQCYYpshJYDo6z9tzeDk8g4KaGFV17TQ/vInH4glys+eTPu8aGorK+L9MnrbtKdi+AYCwrjM5EmRaQYjTSmPUhgJUB/1UBPxUBHwU+31EDR19N4W6eduhJZenLpOjLpPjnUSGZT1J7m5s58/bW/FpcHRRlHPKirikMk554L0tnTq2QyaVJ9WdI5PIk0nkSSfyZFN5cmmTTMoknzbJZS3yGYt81sLMWeRzFlbexszbWHk3AIxkJ18lmH3SwDfZvadaRqq9IkUZxZxcjsSiRXT9+98knnseJ5PBV1lJ/NyTiJVsxU6/geVsJEYagBVWDU8xj6Z4MbF8N42JGPWdtbTPPo36E8rJek0vhHSN6WicXRZjekGI6QVhpkSCVAf97+nGcn/4dY2aUICaUIBj+ow3bYe3elIsbO3iufpOfrdxC/ekNnGk4+cw20dJxiHZmSPZmSXdncPu584EQDc0ghEfgZAPf8ggEPIRiQXwBXT8AQMjYODz6xg+HcOvY/g0dGPnUDc096VraLrmdY+puRWbdowDDQ10t/E8Dbfik1vTaWdXmDt2k9Y76FsLyhvsZldqukbZmMF5sntfWjvdDlQALUAZkAGagM9JKZ8alFQpivK+OLZNetkyuh5+hJ4nnsDq6sIojlN0wkx85S2Y+kaKrZUEUyY5x2CxPZOXtFmsKqylIxKjPVZJU1kt6ZBbqTCowWGFEU4rjDAnFuGwaJipkRA+ffCqbtq2Q3dLmvaGJB2NSToaUnQ0pahoSXFJ0nzXtE1+jc0Rg+KSEJOnx4nHQ4RjASKxAOGon1A0QKjAT6jAh+HXDyhgHQr2JUPuReBGKaUUQkwGvgf8ALgLUAFBUUaA7Pr1dD3yb7ofeYR8fT0EfOgTwwTnQ03ZWkL6anBgQ76ap52TeTM8laWxWdRX1pIqjYOmoTsOU4MGl5QUMa+ogCMKI4iCMP5BPPnnMiat2xK0bu2hdWuC1m0JOhqSmHl7xzQF8SDxyghT5lVQVBGhqCxMYVmISHGQ51Ip/rSthcVdSQoMi2tqQnx6bDk1ocCgpdl2bFL5FMl8kpSZImWmSOfTZK0sGStDzsqRs3JkrSx5O49pmzuGpm1iORaWbblD772Dg+W4D9nZjo3t2Dg47xr2lkHoms71h13PtOI9d0f6fuxLQBgrpZQAUsoNQohxUsr1QghzbzMqijJ4cls20XbfnXQ98RTO9lbQIFiZp+boBNGxGUyfwWpnAi/qp/F6ZDqvlMynobQGJ+bH0GCC4XBevJAjSuMcXhhhVjRMpJ8uLgeKZdq0bkvQtKmb5i3dNG/upqMptaP0NFzop3RMlFknjaF0TAHFVQUUl4fxBw235pNXgIuNW1Br2pzjC3HO+LHIRJp7Gtp56p1GnnmnibNLYlxVU8K4UHBHwS7w7pLaPoW5WStHe6aN9nQ7bZk2OjIddOW66Mp00Z3rJpFPksgnSOYSpM20Wzi8j3ad1tB8GLqOrunoGOi6hq4ZaGjomoaG7g3dbClN073n7NxxaBodU9rdXmoG2L4EhAYhxE+AV4DjgEYhxJlAbuCToyhKf3JdzdS/8xKdS59CX/IWgfWdOO3ud+HSHJEjcjSMLeWtwuksD09jRUzwdsk08rEwFeSYZOU4y8whMg1M3dDGhPZm9EQCJ5XGTruv5mwWO5vByeV2NhNh77xSRwM9EEQLBtFCQfeBs3gcX3EJ/ppq/LW1+KrH4CurwclCsjFJx5YeEg1J0q1pct05fIBPg3KfTm3QIFAdwWdo6IBm2zgdaZzWFLxpYzpuPvW+KAI+7b1cSaCBpv3YxwZQDpQTA2L7MefQi08ZDzUDv9x9CQjX4tYyOhdYCdwIHAFcOfDJUZRDnG3TtnUVW99+iszWZQRb11NZ34BRb2HVBwl2uzVrcqU+6uZX8/KMubxaewTbY1UUkqUomaYonaQ8neCSjYuJZZL4bBvNq+e4zXZosGxechz8toNf8xMI+wiFCokAUTSimkZc04h5BaiG5qBp4FgWTh6cvB/H9OPkfORbguRbw2S2+GB5DiPQDDTv2JwAUIJ7YW6HDbSgD1+BD1/EjxbQ0fyGO/R5L0MDb6i59VLdp5l1vOYpvGYovELb3iYq0L1iWe9zVz7Pw81NvNqdJ+doFDgt6InF2LmN9N4mxAIxyiJllIfLKQmXUBIqpTgYJx4qpigYI2gMwMN1g1FZSdcITYnvfbr3YU/PIRwppXwdOAl4x3sBnCSlXDgoqVGUQ4iVS1O3+mUa5HNk61dT1rOFieY2It0WVS1BuhpD5JuDdOXDWLrG+to4S4+pZpmoIhn2E8rniWaTTGx8hZlb/YTMAgryMcK5KAZ+cIrRepuW6M240GwczcbBJqtbZIw8tm7i6HlsPYcGFBCi0A4TsyPErRhFdpRCJ0xU8+EPaGiBnS1d5oGMA0nTJmM7pNMWFiZGvpNg8ztEmt8m3LmRyNRxFJ55BrHzzydQWzvg+zJtplnespxlTct4s+lNVrSsIGWmsLUwdtG5pArPIqtdRq0/y4crQnx03ETKQiP7LmA47OkO4XTgdXbeCTi4x4EDqICgKPvKcWhvWM/Gt5+maeMygh2bKDC3o/vaaLJ8JDsC2K1+upp9ZOtLKci6szXGYcVsjRUTNVZO0EgHe4AewHsu1ABCuPkl76JRbJQzMTKJabGpiOh0DiuaS9QodB+iSps4PTmc7hxOTw4tkYNEHi2RR0vlvbsJl41Nj5YlQZoW2yFj+0jnA6RMSNlgamD4dHAcLLN3Rh0ogbLjCI87gajWQ7h9C6H7lhG97RHKJ5ZQeukFFF14AXpBwfvapXkrz/KW5SxuWMzSxqWsaF2BaZtoaEwrnsaFky9kTvkcZpfNZnxsPHkH/tnYwe+3NvOz7Vlua67jIzWlXF1TSu0gFkCPNtq+tA/uPbU8GTfLqF5Kae9llkElhJgAbHrmmWcYO3bscCZFUXbIZZJsWfca699ZTGuTJJvehk0bttFNl2OT6vbjdBuEO3VqW2Bcs0N59875m4p9NFbH6KmowiqfQDBSRZFVQMyMErZDhOwAQSeA4Rg75ukx0rT5U7QZabb6etjidJPRcmh6lphuUu74KDeLqciXMNauojwfx2ca70q3HvGhx4M4BX5yfoOU5dCZNmnuyNLYnMbMeh24aKCFs6Scdkx/gpKxYY4+aS6zZs/E5/Nh5W1SPTkSHVl62tP0tGXobE7T2ZikozFFNrWzHkok1UgstZ3KKSVMvOQEqhZMxdhDgbbjONT11PHS9pd4tf5VljQuIW2m0TWdmSUzWVC9gAWVC5hbMZfCQOEel7OoI8Gft7ewsNXd+ScWR7myupSzy4oGtVB9JNi2bRunn346wEQp5eZdv99rQBBC3ABcipsVeDswtU+HOYNGCKEDvwPmAFngE1LK9d53E1ABQRkiVj5PW+sWNm5Zzabtq2lq30wq1ULO7samB182hZ7LYWctzIwOKYNoEsq6obzToaILYuk+y9M1UrEYdlElxKqx4jW0VRXRFTZJ+3Lk/RaW38Hy2diGg2247RgETT8B00c4GySSCxDJ+4naQQqdACEMAhjomoOjWe7J23Gbfs45Du3kaSFDJyl6MMGIUBwcS9gpI9FpkejIvKvrgEhRgJLqAkqqCyirjVI2tpCS6gIMv05PTw+rVq1iyZIltLe3E41GOfnkk5k3bx6GYbxn/4F7Ik52ZmndmqBlaw+NK7bSVJcg67gd5RiYVIyJUHN4NTVT41RNKsI0cixpXMJL21/ipe0vsT2xHYDawlqOqzmOY6uPZUH1AmKB95f1szWT496Gdu5pbGNbJk/E0DmjNMZF5XFOLS2kYDfbMpoNREB4CTgReFZKeaoQYqmUcnC663n3ei8DLpJSfkwIcQzwTSnlxd53EziAgPDAbb8k3dkxoOk9GDn0fyO421rpfY4l29k577uW0ne8997B3jGR2w6MO3bn4mwcx833xnFwsLG9tmHcLlFst0qiY3vL9zpIcesneh2m2GhugzNo73pvuUPbRrdtdO+9ZoPmOGCBZmnotoZuQdCEgA2BvEYorxGwvGqBGji61/a+rmP5dcxgACcYxgmFyBcEyBWF0eJhjJhblTJggF/TMBwTHfdlO2mwM9ikccjgaGlsLYNjZLCNDLaRxTYyOEYWx3h/Nb9tM4CVD2PmQ2TyITStiKJILfHC8RTGaykuH0+seDzBQMUeO4a3bZsNGzawaNEi6urqqKio4JxzzmHSpEn7lA7HcejaUM+Gu55g+/LtdEZqSURrcTQdB5vWgu3Ux9bTFt/K2KklHDvpKI6vOZ7a2MCWQdiOwyudCR5u7uTRli7a8iYBTePoeAGnlcQ4sTjKjGgY4yB4qG1vAWFfahn1HhG9P8/swCRtr07AbXYbKeViIcSRA7HQ237wWcYd/xRFE0Z2WyXKyGcB6b1O5fLx3h9b3nu9i6OhWQE0MwBWwK3NY/qx0wHsfBGW6cc0A5h2CMsOoRFF06Poeghd92P4fBg+H76AgS+go/lssno3mVwHTjpBKJcnbmsYvgwdoSY6Ilvx+evIGivoykNXC2zz6nrqeoBQaAzh8HjC4XFEwuMJRyYQCY8nFBqLrvuZOnUqU6ZMYc2aNSxcuJA77riDI444gnPPPZdAYO958+1lWTZcWciyo1opfPRhTlls4gQmsmHSDPT4PCpaTsVpANaAXRVhw9QkqSmNVE8porAkNCBPHuuaxgnFhZxQXMiPpo5lcVeCZ9q6eba9h+9vqAfcBvkWFBUwLxbhsGiE2YVhxhxgUx0j0b4EhHuAF4AJQojHgIcGN0k7xICuPp8tIYRPSnlAD8TNP+sq1rycRvep5+pGI2fX+xOvmoPT3+9S651nl5HazqHW+1nXQetdjjvjzvsXt4aO7bjvbZwd73c+76R5T5K6C+kd6hj48OH3/voJ4N/xzodma5iOhmmaWHkHK29hmXnMXA4zlyWfy5DPpMmlU1j53hCSx61n722RphMpKiJaUkphaRmR0nJi8XJiFZUUlVcSq6gkHN2Zr55P56h7S+J/q4lpy3x0GN3cWvkPXo8tI244VIX8zCqqYnwgSik2uVQdnZ1Lsay+6zR2BItIeAIF0bFcccVUVq1qYvHixWzfvo0PfvBDlJeXu/vHcWhMNiI7JLJdsqJ1BctbltOVdX/ilZFKjr7ybNo+M5fDX9xG+Z33Yb3xIOFTTkP7wCdpNePUr+ti3dImVi1yT9IF8SDVk4uomlRE5cQY5bWFB9wCqE/fGRy+B2zP5FjcmeC1riSvdSV5fnPTjuMp5tOZHA4xpSDIpHCQsaEAY0MBxngN+oVGYXnEvmQZvQGsB/4JrJFSrhyKhAkhbgYWSynv8z5vk1KO9d5PQJUhKCOAZVlks1kymQzZbJZ0Ok0qlSKdTpNIJEgmkyQSCbq7u+nq6iKZTL5r/lAoREVFBRUVFVRWVlJdXU1lZSV+/3tb8jRzObKpJOmebvfV3UWyq5NUZweJjg4SHW30tLbQ09ZKLp1693oKosSrqolX1RCvqqG42n3F45WkZJItz24mYdZxa+X9rChYS5EeI+WkyTu99zAOEwvKmFIQY1woRLnfoYAUIacbn9mO5mR22S8G2VyEjC9Iu2bRnM3QYZqkbEhZGrFwNROLpzOleDazKuYxtnASPl8YTQug6z7sZIaOu+6k7ba/YHd3U3jmmZTd8HkCU6fRtj1B44YuGjZ00bChk0S7m2mh+9xG38onFFIxroDS2gKKK0Pohpt96DiW+8IBx3KzIb0sxr5DN2vSuwzok1UJDinLZHMqw4Z0lrp0lvpMlm3ZHO25PJoXKtzLAYcCw6DYrxM1DAp9OoWGTsTQiRgaEV0nZGiEdJ2gphMwNAKahl/T8Ovg07QdL8N9HAOf9+SyXzMoLTkKXd//2lEHXIYAIISYAVwIXAw0SSkv2++U7CchxOXAhX3KEL4npTzX+24CKiAoo1A+n6erq4u2tjba29tpbW2lpaWFpqYmslnvxKbrVFZWUltby/jx4xk3bhyFhbuvOdOfTDJBd0szXc2NdDU10tnUSGdTA52N9XS1NL+rvCdSFKe4ugbHV0xPk4FZ0MKDNYtIFFp8dNK1TJ4wnc3dm9ncvZnGZCONyUaaU81krN4g4BDWoNTnUOKzKTYcynSDyWYxBT4LoyBJ2JfDeG8G2R7oaJrPLcPIWzhmHmzQfD60gN+9o8Px+iCwd5QfOdho2sGfHZyr/ibnzvjEfs93wGUIQog5wJm4zyXAzgfUBtuDwJlCiFdw7+GvG6L1Ksqg8fv9lJWVUVZW9q7xjuPQ1dVFfX099fX1bN++nWXLlrFkyRIAysvLmTx5MpMmTWLChAl7zZ8PFUQJFUSpmPDeAl4zn6erqYGOhnra67fR0VBPR8M2OreuItXVCS1wzmY3fc2hR2kPPc+s8fOYOWUmsfKTKawup7C0jEAsStawSJmpHe316OgUBAooDBRi523uvvtuNi/fzIUXXsgRRxxGPt9FPt+BZSUwzQSmlcC20lhWBtvOYNs5bMfEsXPe1bx7orezGTKrV5NZvRonn8VfW0v4sMPxV1SgaYbXxrRbwI+jk01ZpLpNUl0myc48qW6TbNLGcdzvQSMYDhCKBgkXBN1WUSNBAhE/oYIggbCfgGFA1sZO2zhZGydjucOcg5OzcXI2dt6GvIWdd8B0sE136FgOWF4POV5+Zu8+chyNjAFZQyOrQ07XyOkaeR1yuoOl6Zia+4yHqbtlVbYOtqZhufmbnB8anN4J9iXLqAvYCHxbSvnYoKRiP6k7BOVQYFkWDQ0NbN68mY0bN1JXV4dpmvh8PiZOnMi0adMQQhCLDdwTt9lUkvb67TzwwnJeXrKaCYF15M1GipMhgv1UJ/EFghTE44QLY4QKY4SjhQQiBQTCYYLhCJrPx/IVK2hqaeWIefOYMnUqum5AbwuqXq0y27ZxbAvHtrEsC9sysU0LyzSxLRPLdF9mMkFq5UpSa9Zg5fPo5WX4J01CKynBti1s08S2bWzTxLIsHMtyx1sWlmlh5kzMvIllWtim+73TWwsNvFpqXhU23JP4zl7OnB1jhtt5N3yNGSeevN/zDUS1Ux9ujZ+zgaOAZinlsLZjpAKCcijK5/PU1dWxdu1a1q5dS0eHW3V67NixTJ8+nZkzZ1JSUrKXpey752Qzn73rDaoq1pMqupNw3s83N1xLta8Ue7KBGbdJdrtlGOlED5mebtKJHnKpFNlUCtsa+Iobhs+Hbrg1qTTThFQKzTTRfX788TiBkhL0QMCbxkA3fGi6jq4ZODmb/9/encdHVd/7H3+dc2bJOkNCEhJCCCHAN4QtRQmLoAIKgSug9tpFarWoVFuvta3V3tb2lra2vbf13npb69IfrXrdKi6IxULZhRAgIBi2HBbZMRCBkGVIZv39MZMYICEBkpksn6ePeczhzJwzn6/ivOd7lu+XWj/U+QnUBn/xa4H60UQ1dIsBNoOAYRDQdXyahjf0Q9/rB483gMcHPl/wruz6WdU+n9ym8ZUNFyw3eTHSlV2hpOk6k+fcypDxAy9727a47LQHkA5kAjHAocuuQghx1axWK9nZ2WRnZ1NQUEB5eTmlpaXs3r2b5cuXs3z5clJTU8nNzSU3N/eiw1KXa6JK4S93j2LOS9Db/3303vP5j8F/YV7Vwwzd3Rc9zkrc2FHE3p6GEdvESXCPB29dHV6PG1d1FQvefJPKykpumzXrvOAKDvGsoekGmq43fJHrhoFhCV5Kq9d/uV9wmWfA66Vq+QpOv/wy59Z9hGazET9lCo5bbsVIyMZ9qIq6Q5V4Pq1uuNdFT7BhTYvFlhaLpVcM1uQYLMnR6FGXN19zwB/A6/E3TMNZP/2mz/v5wx8Kjvp5mQP+4DzM9cuBQKP5mBvmZa6fg7nRVWz+QMM8zJqu0Tc37bJqba3WXmX0LvCuaZo726WKyyQ9BCHOV1FRwe7du9m1axdHjhwBgucd6sMhJSXliq+ZL9z3GXNeLKZvsoeYvn/lSPUhfjnwJ+TvHkiteQbNqhM9PJnY0anYMuKb/ZyKigr+/Oc/Y7Vauf/++4m9wnGMmuKrdlO9bjfV60rxnbWgx6bUv4IlxUZUbhr2vg5sGfEY8d137KI2ucqoo5FAEKJ5Z8+epbS0lF27dnHoULBDn5CQQE5ODkopMjIymh1iojlr95Yz58VirsmKwtL7r5SUf8yT45+kIG4S1YXHcW07ScDtx5oWS8wXUogeloQlIeqi/Rw9epQXX3yRzMxMZs+eja5f2bX6vhoP7oNnqfvkLHX7K/CUBS+z1WwGtsw48J6gdsdaatYsIuCuw0hOIu6GG4i74QZiR4/GaMPzLp2JBIIQ3VhVVRWmaVJaWsqBAwfw+XzY7Xb69+/PgAEDyMrKIiEhoVW9hzeLj/DY2yXcOSaVk9HPUnyimCfHP8kt/W/BX+vFta2cmuIyPMeqAbBlxBOlErBn9wj2HCzBL//i4mIWL17MtGnTGD16dIufG/AH8Ja7cB+pwn04eAjIeyIUAFYdW6YDe3YP7NlObOnxwTkVQnyVlVStXEn1mjXUrF2Hv7oaNI2owYOJyc8nOi+P6OHDsKSldbm7jpsigSCEAKC2tpYDBw6wd+9e9u7dS1VVFQBOp5N+/frRp08fMjIySE5ObrYH8asPdvPCh5/w0xnZFFb/ls0nNvPr8b9mev/pDe/xnjqHa/tnnNv+GZ7j1cHj3lYda2oslpTg8fqFu5dz+LOjfGPm10hOSibgC45H5Xd58VW58VW68Z06h+ekC8/Jc8GzuoAWZWDLiMfe34k9y4mtz+dB05KAx4Nr61Zcm4pxbdrEuW3bgrPDAUbPnkTl5GAfOBD7wIHYsrKwZfbFSEzsUkEhgSCEuEggEKC8vJyDBw9y4MABDh06hMsV/NVtsVjo1atXwyMpKYmePXvicDgIoDH35c2s3lPOi3NG8Jd9T/DRyY946oanuCnzpos+x+/yUHcgeGjHU1aD56QLf5UHF3W8Y99IbCCKme5rMbjgS10Dw2HD0isWa0pM8CRwRjyWpOjgrGltwO92U2eanCspoXb7Dur27KFu/xtot5AAABj+SURBVH4CdZ9fX6vHxmJNT8eSloo1NQ1LSjKWnj0xevYMPjudGE4nusOB3oqxmyJNAkEI0aJAIMCZM2c4evQox44d48SJE5SVlVFb+/mQFIZh4HA4iIt3UHy8ltqAhS+P68+io29x6Nwhvn3ttxmZPhKbzYbVasVqtWKxWNB1HV3XG35p+10efNUeSktLeXvlIsYOHsWE4WNAh4BNQ4uzQrSOnwA+n6/h4Q3dW3DhcnPr/KF7GuqXm3sEAoGG54Dfj6+mBp/Lhe/cOXznzuGvrcPvrsPvdhPwBi+lDTTqNTQsazoYBhg66Hpw6k/DCE3xqQefGy/Xj6dVv77+8tSG/V3wTP3H6BTMnElWTs5l/3dui8tOhRBdnKZpJCYmkpiYyPDhw4FgSFRVVTUMs3Hq1KmGMZmyolxUVVWzce0xeoX+Kf57McUUN/sZ9aGgaRr1P0Q1TaNodzFFu5vf7mrVB1L9wzCMhloah1Xj+nSbDc1uhx490DQNIzSukBYIEPD5wOsNhoPXC6E/E7oRjoaHn4DXB35fcAj20CPgD46RhL/+TuYLhplv5jd6w1hJgQCezZvhCgKhJRIIQogmaZqGw+HA4XCQlZV10evPrd7H75bs4okp/cnvpzNv7TzcdW4eHPogibZEPB7Peb/Y66+x9/v9Db0Fj8fDli1bcDgcjBgxouELu/5L22KxXLRsGEazyxc+GvdMOqpAIDRnh89HwOsN3jldfwd1Q4iEBtjz+0HXsaamtkstEghCiCsy9/psCvef4jerjvD3f5vAU7c/xdf/8XX+69h/8cr0V0iNbd2XVmJiIkuWLCElJYXc3Nx2rrrj0TQtdKjJQIvweYjON2C3EKJD0HWNp+4Ygd1i8PjbJfSOTefZm56lxlPDA8seaJjroCWjRo2iV69eLF26FHfoqh8RGRIIQogrluKI4qe35LLl0Bn+b8MhVKLi6YlPc7jqMA+vfJhab22L+zAMg+nTp3P27FnWrl0bhqpFcyQQhBBX5faR6Vw/KJn/XFLK0TMu8tPy+dWEX7H15FYe//BxfH5fi/vIzMxk2LBhFBUVNdwfIcJPAkEIcVU0TeNXtw0F4Efv7iAQCFDQr4DH8x9n5ZGVPLnxSVpzefvEiRPx+/2sWbOmvUsWzZBAEEJctT4JMTxekMOHe8pZuO0YALMHz2bO0Dks2LOA50ueb3EfiYmJjBw5ko8++ojTp0+3d8miCRIIQog2cdeYTPIyevDk4lIqa4PTZT4y8hFmZs/kmW3P8Naet1rcxw033ICu66xataq9yxVNkEAQQrQJXdf4+awhnKqp43+W7QGCh5N+Nu5njE8fzy82/IJlh5Zdch/x8fGMHj2a7du3c+LEiXCULRqRQBBCtJnhfXpwZ35fXi46xO5PKwGw6lb++8b/ZnjScB7/8HGKjhddch/jx4/HbrezcuXKcJQsGpFAEEK0qR9MVTiiLPz0vR0NJ5OjLdH8cfIf6efsx3dWfYft5dub3T46Oppx48ZhmiZlZWXhKlsggSCEaGM9Ymz8cFoOxQfPNJxgBnDanTx/0/P0jOrJN5d/k92ndje7j/z8fGw2m9yXEGYSCEKINnfHNRmM6OPkN/8opabO27A+OSaZ+VPnE2eN4/5l92OeNpvcPjo6mvz8fHbu3Mlnn30WrrK7PQkEIUSb03WNn84YwonKOp5dvf+813rH9Wb+lPnYDTtzl81lf8X+JvcxZswYLBYL69atC0fJAgkEIUQ7uSYzgdu+kM4Laz/hyGnXea9lODKYP2U+uqYzZ+kcSk+XXrR9XFwcI0eOpKSkhIqKinCV3a1JIAgh2s3jBTkYmsav/3Hx+YJ+zn78depfsRk25iydw7aT2y56z3XXXQdAYWFhu9cqJBCEEO0o1RnFt27M5oPtZRTtP3XR6/2c/Xip4CUS7AnMXTaXDZ9uOO91p9PJiBEj2Lp1KzU1NeEqu9uSQBBCtKv7r+9Peo9o5r2/E5//4jGNesf15qVpL5Eel86Dyx9k0f5F570+btw4vF4vxcXtN6uaCJJAEEK0qyirwY//ZTClZVW8UXy4yfckRSfx0rSXuCblGn687sf8cesfG+5hSE5OZtCgQWzatEnmS2hnEghCiHY3bWgq+VmJ/G6pyVmXp8n3OGwOnr3pWW4bcBvPlzzPYx8+hssTPBk9btw4XC4XH3/8cTjL7nYkEIQQ7U7TNP5jRi4V5zw8vWJvs++zGlbmjZvHIyMf4Z+H/slXF3+V/RX7yczMpHfv3hQVFeH3+5vdXlwdCQQhRFgM6e3kK6P68nLRQfadbH4SHE3TuHfYvbxw8wtU1FXw1cVfZdH+RYwdO5bTp09jmk3fzCaungSCECJsHp0yiGibwbz3d7U4ac7otNG8NeMtcnvm8kThE7xw8gVsCTbWr18fpmq7HwkEIUTY9Iyz872bB7F272cs3dnywHXJMcnMnzKfR699lKJPi3gv8T3WnVnHkSNHwlBt9yOBIIQIq7vGZJKTGs/P39+Fy+1t8f2GbnD3kLtZMGMBAxIGsDl5M3NXz73kiKniykggCCHCymLo/HzWUI6freWZVftavV2WM4uXp7/Ml5xfotxTzp0f3MkP1/6Qg2cPtl+x3YwEghAi7PKzErn9C+m88OEnfFJe3ertDN3g4YkPU3C0gEmxk1hxaAWz3pvFY2seY8+ZPe1YcfcggSCEiIgfTs8hymLwk0YT6bSG0+kkLzeP1L2pLLxlIfcMuYc1R9fwxUVfZM7SOSw5sASPr+l7HcSlWcL1QUopJ/AK4ABswPdM0yxSSo0Bnga8wD9N05ynlNKBPwEjgDrgPtM0W9+3FEJ0eCnxUTw+LYcnFu5gwZajfOnajFZvO2bMGHbs2MHh3Yf57tjvMmfoHBbsWcBbe97iBx/+gAR7AlP6TWFqv6mMTBmJoRvt2JKuI5w9hO8BK0zTvAG4B3gmtP454E5gPDBaKTUSuBWIMk1zLPBD4Kkw1imECJM78/uSn5XIL/++i5OVta3erk+fPvTt25eNGzfi8/lw2p3cN+w+Prj9A5676Tny0/JZtH8Rc5bO4aa3buInhT9hyYElVNTKMNqXErYeAvA/BH/t139urVLKAdhN09wPoJRaCkwG0oAlAKZpblBKXRvGOoUQYaLrGr+5fRjTnl7LEwt38Pxd16BpWqu2HTt2LH/7298oLS1lyJAhwf1pOtelX8d16dfh8rj48NiHLD+0nJWHV7Jw30I0NAYmDCQvOY+8lDyGJA0hMz5TehAh7RIISql7ge9esPobpmkWK6VSCR46eoTg4aPKRu+pAvqH1p9ttN6nlLKYptnyNWpCiE6lf3Ic3715EL/5RykfbC/jX4antWo7pRSJiYkUFhaSm5t7UZDEWGMo6FdAQb8CfH4fO07tYP3x9Ww7uY3FBxbz5p43AYi2RDMwYSDZzmz6OfuR5cgiIz6D3nG9ibHGtHl7O7J2CQTTNOcD8y9cr5QaBrwBPGqa5ppQDyG+0VvigQog5oL1uoSBEF3XfeOzWFzyKU8s3M41mQmkOqNa3EbXdcaOHcvixYs5fPgwmZmZzb7X0A1GJI9gRPIIAHx+H/sq9lF6urThseboGt7d9+552yXYE0iNTSUpOomUmBQSoxJJiEogISqBHvYexNvicdgcxFnjiLXGEm2JbnUPpyMK50nlXGAB8GXTND8GME2zUinlVkplA58AU4F5QB9gBvBm6KSz3IEiRBdmMXR+/5U8ZvxhHd95Yyuv3T8GQ2/5i3XEiBGsXLmS9evXXzIQLmToBipRoRIVs5jVsP5s3VkOVh7kWNUxjtcc51j1MU66TlLuKmfXqV2cqTuDP9D84HoaGtGWaKIsUcFnIwqbYcNu2LEZNqy6FatuxaJbGh6GZmDRLeiajqEZGLrRsKxpGjo6uqajaRoaGhbdwq0DbiU1NrXV7W2tcJ5D+DUQBTytlAI4a5rmLOAB4FXAIHiV0UalVDFws1JqPaAB3whjnUKICMhOjuPns4by6IKPeWbVPh6ePLDFbWw2G/n5+axZs4bPPvuMpKSkq6rBaXee15O4kD/gp8pdxena05ytO0ulu5IqdxVV7ipcXhc1nhpcHhd1vjpqvbXU+mpx+9zU+epw+9zUemvx+D24fW58AR9evxdvwIvf78cb8OIL+PD7/cHngJ8AAfwB/3nLuqaT3SO7cwdC6Mu/qfUbgDEXrPMTDAohRDfyxZHprNtbzu+X72FM/57kZyW2uM2oUaNYt24dRUVFzJgxo13r0zUdp92J0+5s18+5lEAg0G6HpeTGNCFEh6FpGr+8bRh9E2N46LWPOF5xrsVt4uLiyMvLY9u2bVRXt/6u586qPc9RSCAIITqUOLuF5++6lnNuH3NeLKa6ruXrScaOHYvf76eoqCgMFXZdEghCiA5HpcbzzOyR7D1ZzUOvfYTXd+lZ0pKSksjNzaW4uJhz51ruVYimSSAIITqk6wcl84tZQ1ltlvPTRTtbHO9owoQJuN1uNm3aFKYKux4JBCFEh3Xn6L48eGM2r208zI/e3Y7P33wopKamMmjQIDZs2EBdXV2z7xPNk0AQQnRoj01VPDRxAK9vOsL339x2ycNHEyZM4Ny5c2zZsiWMFXYdEghCiA5N0zQenar4wVTFwm3HefDVj5o90ZyRkUFWVhbr16/H45EhsC+XBIIQolP49sQBzJs5hBW7TzDjD+vYdbyyyfddf/31VFdXs3nz5jBX2PlJIAghOo27x/Xj9fvHUFPn5bY/FfLqxkP4LzivkJWVRVZWFmvXrpVzCZdJAkEI0amM7t+TD74zgfysRH787g5uf3Y9Ww+fOe89kydPxuVyyX0Jl0kCQQjR6STF2XnpG/n89l+Hc6ziHLf9aT2PvLGV3Z8GDyP16dOHnJwc1q9fT01NTYSr7TwkEIQQnZKua9xxbQarHr2Rb92YzZKdZUx7ei1fer6Iv5ccZ9yEG3C73axbty7SpXYa4RztVAgh2lyc3cJjBTnMvb4/b24+wstFh3jota1EWXVmOPuwYeMm0gcNZ0i/1E49V0E4SCAIIbqEHjE25l6fzb3j+1O0/xTLdpWxdqefcb5j/PYvb1JiHUxeRg8GpcaTnRxHdnIsfRJiSIqzt2ruhe5AAkEI0aUYusb4gUmMH5hEYOYQ3llsxbJ5Pb376mytqKVw3yncjW5us+gaKfF2kuLtJMbaSIyx4Yi24oiyEB9lJcZuEGMziLZaiLYZ2C06UVYDm6Fjs2jYDAOLoWHRNSyG3rCsa58/650kcCQQhBBdlqZpzJw6kaP7d2NUl/KLhx5A0w2OnnGxv7ya4xW1fHr2HJ+ereVUtZvTNW72nqimstZDdZ2XFoZPuiyGrqFrwZp0DXRNQwvVGHwOLWuct57Qa4T+ZNE1fvPFYdyoUtquuBAJBCFEl2a1Wpk2bRqvvfYaGzdu5LrrriOzZyyZPWMvuZ3fH6DG7cXl9oUeXmo9fuo8Puq8fuq8Pty+AB6vH4/Pj9cfwBt69vkDDc/+QAC/P4AvECAQoOE5EAjgDxBc5vN1AT5fR8MyDcuGDhmJMe3y70oCQQjR5Q0aNAilFKtXr2bo0KE4nS3PeKbrGvFRVuKjrGGosGOQy06FEN1CQUEBAAsXLsTvv/T8Ct2VBIIQoltISEigoKCAAwcOsGHDhkiX0yFJIAghuo2RI0eSk5PDihUrKCsri3Q5HY4EghCi29A0jRkzZhAdHc3bb78tQ2RfQAJBCNGtxMbGcuutt1JeXs7777/f4tSc3YkEghCi2xkwYACTJk2ipKSENWvWRLqcDkMuOxVCdEsTJkzg9OnTrF69moSEBEaMGBHpkiJOAkEI0S1pmsYtt9xCRUUF7733HvHx8fTv3z/SZUWUHDISQnRbFouFL3/5yyQlJfHqq69immakS4ooCQQhRLcWHR3NPffcQ69evXjjjTcoKSmJdEkRI4EghOj2YmJiuPvuu8nMzOSdd96hsLCwW97NLIEghBCA3W5n9uzZ5ObmsmzZMl5//fVuN/2mBIIQQoRYrVbuuOMOpk+fzieffMJzzz3Hvn37Il1W2EggCCFEI5qmkZ+fz3333YfNZuOVV17h9ddf59SpU5Eurd1JIAghRBPS0tJ44IEHmDx5MgcOHOCZZ55h8eLFXToY5D4EIYRohtVqZcKECeTl5bFq1Sq2bNlCcXExSilGjRpFVlYWhmFEusw2I4EghBAtiI+PZ+bMmUycOJHi4mI2b96MaZrExMQwePBgBg8eTN++fbHZbJEu9apIIAghRCvFx8czadIkJkyYwL59+9i5cyclJSVs2bIFXddJT08nMzOTtLQ00tLSSEhIQNO0lnfcQUggCCHEZbJarQ09A7fbzeHDhzl48CAHDhygsLCwYQRVm81GYmIiPXv2JDExEafTicPhID4+ntjYWGJiYrBYOs7XcMepRAghOiGbzcaAAQMYMGAAAB6Ph5MnT1JWVsaJEyc4ffo0x48fZ9euXU0OtW2324mOjiYqKgq73Y7dbsdms2Gz2bBarVgsFqxWK4ZhNCwPGTKE6OjoNm9L2ANBKZUDbAR6maZZq5QaAzwNeIF/mqY5TymlA38CRgB1wH2maXafi4GFEJ2W1WolPT2d9PT089b7fD5qamqorKyksrKSmpoaXC4XNTU11NbWUldXR21tLVVVVbjdburq6vB6vXg8Hnw+33n7slgs5OXltXntYQ0EpZQDeIrgl3y954AvAp8Ai5VSI4F+QJRpmmNDgfEUMCuctQohRFsyDAOHw4HD4bjsbf1+Pz6fD6/XSyAQICYmph0qDON9CEopDXgB+BHgCq1zAHbTNPebphkAlgKTgfHAEgDTNDcA14arTiGE6Gh0XcdqtRIdHd1uYQDt1ENQSt0LfPeC1YeAN0zT/FgpVb/OAVQ2ek8V0D+0/myj9T6llMU0TW971CuEEKKdAsE0zfnA/MbrlFL7gHtDYZEK/BO4BYhv9LZ4oAKIuWC9LmEghBDtK2znEEzTHFC/rJQ6CEwJnVR2K6WyCZ5DmArMA/oAM4A3Q+cQtoerTiGE6K46wmWnDwCvAgbBq4w2KqWKgZuVUusBDfhGJAsUQojuICKBYJpmv0bLG4AxF7zuJxgUQgghwkRGOxVCCAF0jENGV8IAKCsri3QdQgjRaTT6zmxyiNbOGghpALNnz450HUII0RmlAfsvXNlZA6EYmAB8CvhaeK8QQoggg2AYFDf1otbUYEtCCCG6HzmpLIQQApBAEEIIEdJZzyF0SEqprxAcjuMU8IRpmlURLumKKKUeAfKAgcCrpmn+KcIlXTGlVB7wvwTvhH/JNM1VES7piimlrgG+D3iAx0zTPBHhkq6KUmoScKdpmvdFupa20tnbJD2EtjUTuAd4Gfh6ZEu5cqZp/h6YC+wkODx5Z5YPlBG8+GBnhGu5WlHAt4DFwNgI13JVlFIDgJEE29QldIU2SQ+hbf0B+DNwhM5/9dNXgXdCd413ZuuAvwG9gEeBxyJbzpUzTbNQKTWOYDvuiHQ9VyM04dXvlFKvRLqWKxXqSd8U+mORaZpP0snbJIHQttKA+4CJQEaEa7laE4D7I11EG8gjeHnyGTr533el1ChgMzAN+HeCwSAiJNST/n2k62hLnfp/kHBSSo0G/tM0zRsvMcVnBfAiwd7BNyNV66W0sh0AltCkRR1WK9tykGDPzUNwJN0OqZVtcQB/ITjg4x8iVmwLLuPvWIfVFdpwJSQQWkEp9RhwF1ATWnUrTUzxaZrmSmBlhMpsUWvbAWCa5j0RKbKVLuO/yXpgfYTKbJXLaMsKYEWEymyVy/k7BmCa5tfCX+WlXW4bLtQR29RaclK5dfYDtzf6c2ed4rOrtAOkLR1VV2hLV2jDFZFAaAXTNN8meMihXpNTfIa3qsvXVdoB0paOqiu0pSu04UpJIFyZSrrGFJ9dpR0gbemoukJbukIbWkUC4coUAtMBOvkUn12lHSBt6ai6Qlu6QhtapUt2e8LgXbrGFJ9dpR0gbemoukJbukIbWkVGOxVCCAHIISMhhBAhEghCCCEACQQhhBAhEghCCCEACQQhhBAhEghCCCEACQQhhBAhEghCXCGl1GqlVM4lXi8LZz1CXC0JBCGEEIAMXSFEqyilHMD/A3oASQSnSq1/7WdADpACJAD/ZprmOsCulHoN6AucAv6V4FSezxKcd7cn8HPTNBeGryVCNE96CEK0zgDgDdM0pwC3AN+74HWXaZqTgK8Bz4TWxQE/Mk1zPOAEvkAwOJ4yTfNm4CHg2+EoXojWkB6CEK1TBjyilLqd4HDI1gteXwlgmuZOpVRqaN1p0zQPNto+huD8zk8ope4FAk3sR4iIkR6CEK3zKFAUmh5xAcFRLxu7BkApNRQ4FlrX1MiRvwBeNk3zLmBVE/sRImKkhyBE67wPPKuUmk3wfIAXsDd6/QtKqRVALHD/JfazAPjf0BVIRwiejxCiQ5Dhr4W4SqGTymWmaT4X6VqEuBpyyEgIIQQgPQQhhBAh0kMQQggBSCAIIYQIkUAQQggBSCAIIYQIkUAQQggBSCAIIYQI+f8I3/yQ4HpyEAAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "alphas = 10**np.linspace(10,-2,100)*0.5\n",
    "\n",
    "ridge = Ridge()\n",
    "coefs = []\n",
    "\n",
    "for a in alphas:\n",
    "    ridge.set_params(alpha=a)\n",
    "    ridge.fit(scale(X), y)\n",
    "    coefs.append(ridge.coef_)\n",
    "\n",
    "ax = plt.gca()\n",
    "ax.plot(alphas, coefs)\n",
    "ax.set_xscale('log')\n",
    "ax.set_xlim(ax.get_xlim()[::-1])  # reverse axis\n",
    "plt.axis('tight')\n",
    "plt.xlabel('alpha')\n",
    "plt.ylabel('weights')\n",
    "plt.title('Ridge coefficients as a function of the regularization');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above plot shows that the Ridge coefficients get larger when we decrease alpha."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Alpha = 4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler().fit(X_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "193147.46143016344"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge2 = Ridge(alpha=len(X_)*11498/2)\n",
    "ridge2.fit(scaler.transform(X_train), y_train)\n",
    "pred = ridge2.predict(scaler.transform(X_test))\n",
    "mean_squared_error(y_test, pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat          0.015146\n",
       "Hits           0.016050\n",
       "HmRun          0.013561\n",
       "Runs           0.015681\n",
       "RBI            0.016782\n",
       "Walks          0.019662\n",
       "Years          0.010390\n",
       "CAtBat         0.016570\n",
       "CHits          0.017627\n",
       "CHmRun         0.015072\n",
       "CRuns          0.018771\n",
       "CRBI           0.016697\n",
       "CWalks         0.016821\n",
       "PutOuts        0.003228\n",
       "Assists       -0.007600\n",
       "Errors         0.013672\n",
       "League_N       0.003519\n",
       "Division_W     0.003339\n",
       "NewLeague_N    0.003499\n",
       "dtype: float64"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(ridge2.coef_.flatten(), index=X.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Alpha = $10^{10}$ \n",
    "This big penalty shrinks the coefficients to a very large degree and makes the model more biased, resulting in a higher MSE."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "193253.09741651407"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge2.set_params(alpha=10**10)\n",
    "ridge2.fit(scale(X_train), y_train)\n",
    "pred = ridge2.predict(scale(X_test))\n",
    "mean_squared_error(y_test, pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Compute the regularization path using RidgeCV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RidgeCV(alphas=array([5.00000e+09, 3.78232e+09, ..., 6.60971e-03, 5.00000e-03]),\n",
       "    cv=None, fit_intercept=True, gcv_mode=None, normalize=False,\n",
       "    scoring='neg_mean_squared_error', store_cv_values=False)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridgecv = RidgeCV(alphas=alphas, scoring='neg_mean_squared_error')\n",
    "ridgecv.fit(scale(X_train), y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "115.5064850041579"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridgecv.alpha_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "97384.92959172592"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge2.set_params(alpha=ridgecv.alpha_)\n",
    "ridge2.fit(scale(X_train), y_train)\n",
    "mean_squared_error(y_test, ridge2.predict(scale(X_test)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat           7.576771\n",
       "Hits           22.596030\n",
       "HmRun          18.971990\n",
       "Runs           20.193945\n",
       "RBI            21.063875\n",
       "Walks          55.713281\n",
       "Years          -4.687149\n",
       "CAtBat         20.496892\n",
       "CHits          29.230247\n",
       "CHmRun         14.293124\n",
       "CRuns          35.881788\n",
       "CRBI           20.212172\n",
       "CWalks         24.419768\n",
       "PutOuts        16.128910\n",
       "Assists       -44.102264\n",
       "Errors         54.624503\n",
       "League_N        5.771464\n",
       "Division_W     -0.293713\n",
       "NewLeague_N    11.137518\n",
       "dtype: float64"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(ridge2.coef_.flatten(), index=X.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python-glmnet (update 2016-08-29)\n",
    "This relatively new module is a wrapper for the fortran library used in the R package `glmnet`. It gives mostly the exact same results as described in the book. However, the `predict()` method does not give you the regression *coefficients* for lambda values not in the lambda_path. It only returns the predicted values.\n",
    "https://github.com/civisanalytics/python-glmnet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=0, cut_point=1.0, fit_intercept=True,\n",
       "      lambda_path=array([1.00000e+10, 7.56463e+09, ..., 1.32194e-02, 1.00000e-02]),\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=3, random_state=None, scoring=None, standardize=True,\n",
       "      tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "grid = 10**np.linspace(10,-2,100)\n",
    "\n",
    "ridge3 = gln.ElasticNet(alpha=0, lambda_path=grid)\n",
    "ridge3.fit(X, y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Lambda 11498"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "11497.569953977356"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge3.lambda_path_[49]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Intercept: 407.356\n"
     ]
    }
   ],
   "source": [
    "print('Intercept: {:.3f}'.format(ridge3.intercept_path_[49]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat          0.037\n",
       "Hits           0.138\n",
       "HmRun          0.525\n",
       "Runs           0.231\n",
       "RBI            0.240\n",
       "Walks          0.290\n",
       "Years          1.108\n",
       "CAtBat         0.003\n",
       "CHits          0.012\n",
       "CHmRun         0.088\n",
       "CRuns          0.023\n",
       "CRBI           0.024\n",
       "CWalks         0.025\n",
       "PutOuts        0.016\n",
       "Assists        0.003\n",
       "Errors        -0.021\n",
       "League_N       0.085\n",
       "Division_W    -6.215\n",
       "NewLeague_N    0.301\n",
       "dtype: float64"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(np.round(ridge3.coef_path_[:,49], decimals=3), index=X.columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6.3606122865384505"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(np.sum(ridge3.coef_path_[:,49]**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Lambda 705"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "705.4802310718645"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge3.lambda_path_[59]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Intercept: 54.325\n"
     ]
    }
   ],
   "source": [
    "print('Intercept: {:.3f}'.format(ridge3.intercept_path_[59]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat           0.112\n",
       "Hits            0.656\n",
       "HmRun           1.180\n",
       "Runs            0.938\n",
       "RBI             0.847\n",
       "Walks           1.320\n",
       "Years           2.596\n",
       "CAtBat          0.011\n",
       "CHits           0.047\n",
       "CHmRun          0.338\n",
       "CRuns           0.094\n",
       "CRBI            0.098\n",
       "CWalks          0.072\n",
       "PutOuts         0.119\n",
       "Assists         0.016\n",
       "Errors         -0.704\n",
       "League_N       13.684\n",
       "Division_W    -54.659\n",
       "NewLeague_N     8.612\n",
       "dtype: float64"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.Series(np.round(ridge3.coef_path_[:,59], decimals=3), index=X.columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "57.11003436702412"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(np.sum(ridge3.coef_path_[:,59]**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fit model using just the training set."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=0, cut_point=1.0, fit_intercept=True,\n",
       "      lambda_path=array([1.00000e+10, 7.56463e+09, ..., 1.32194e-02, 1.00000e-02]),\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=3, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-12, verbose=False)"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge4 = gln.ElasticNet(alpha=0, lambda_path=grid, scoring='mean_squared_error', tol=1e-12)\n",
    "ridge4.fit(X_train, y_train.values.ravel())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "101036.83230892917"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# prediction using lambda = 4\n",
    "pred = ridge4.predict(X_test, lamb=4)\n",
    "mean_squared_error(y_test.values.ravel(), pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Lambda chosen by cross validation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=0, cut_point=1.0, fit_intercept=True, lambda_path=None,\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=3, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge5 = gln.ElasticNet(alpha=0, scoring='mean_squared_error')\n",
    "ridge5.fit(X_train, y_train.values.ravel())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "255.04348848905948"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Lambda with best CV performance\n",
    "ridge5.lambda_max_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1974.70910641])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Lambda larger than lambda_max_, but with a CV score that is within 1 standard deviation away from lambda_max_ \n",
    "ridge5.lambda_best_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA4UAAAFuCAYAAAA2zL3IAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3XuYnWV97//3TE5kyEFMyEGSNB7wWzRFNqhYAU0DQsF2u8uvioDFUg/INhSsVsADRS7AQlEErFqgFJRDtyi698atqFQqRARtRQHllqIROSQhMSTkfJrfH2tNMgkza62ZtZ71PGs979d1eWXNs5418514k1mfue/7e/f09/cjSZIkSSqn3rwLkCRJkiTlx1AoSZIkSSVmKJQkSZKkEjMUSpIkSVKJGQolSZIkqcTG5l1A1iJiAvAa4Glge87lSJIkSVK7jQFmAz9KKW3e88muD4VUAuHdeRchSZIkSTk7Arhnz4tlCIVPA9x0003MmjUr71okSZIkqa2WLVvGySefDNVstKcyhMLtALNmzWLOnDl51yKpAatWrQJg2rRpOVciDc0xKknqUENup7PRjKTCWbNmDWvWrMm7DGlYjlFJUjcxFEqSJElSiRkKJUmSJKnEDIWSJEmSVGKGQkmSJEkqsTJ0H5XUYV7ykpfkXYJUk2NUktRNnCmUJEmSpBIzFEoqnJUrV7Jy5cq8y5CG5RiVJHUTQ6Gkwlm7di1r167NuwxpWI5RSVI3MRRKkiRJUokZCiVJkiSpxAyFkiRJklRiHkkhqXB6e/19lYrNMSpJGrB8+XKeeeaZYZ/fd999mTlzZhsrGjlDoaTCmT9/ft4lSDU5RiVJA2bOnLkz9P3qV78COu88W3/VKUmSJEkl5kyhpMJZsWIFADNmzMi5EmlojlFJKo9uWB5aj6FQUuGsW7cO8A23issxKkmdpV6w6+vrY8OGDcM+PxD8OnV5aD2GQkmSJEkdrZHZvAULFgD19/11a/CrxVAoSZIkKXf1gl0tIwl9ej5DoSRJkqTMtWo2z9DXeoZCSYUzdqz/NKnYHKOS9HytXMKp9vKnmqTCmTdvXt4lSDU5RiWVVaOdOA19ncVQKEmSJAlwtq+sDIWSCmfZsmUAzJo1K+dKpKE5RiV1q5kzZ+48c8/QVx6GQkmFU+ucIKkIHKOSOlUZDmLXyBkKJUmSpC7ivj+NVG/eBUgqvvvuu48PfOADLft8ixYtYvPmzcM+v2XLFt75zne27Oup+xV5jN52221cdtllTdVz4403NvV6Sd1l+fLlPPTQQ8P+D2DBggUsWLCAvr4++vr6dn68YMECZwL1PM4USpJUcJ///Od5xzvekXcZkgrCfX9qNUOhpFH71re+xU033bTz4yuuuIJHH32Uq6++mnHjxrFs2TLe/va388Mf/pBHHnmEU045hZNOOgmA8847jyeffJJp06ZxySWXsH37dj70oQ+xdu1apk2bRk9PDwD3338/n/3sZwHYtGkTl1xyCS9+8Yt3fs3bbruN733ve2zatIlnnnmGU045hTvvvJNHH32UD3/4wxx11FHceOONfPvb32bbtm1MnjyZq666iltvvZX//M//5FOf+hRnn302Bx54ICeffHIb//bUDkUYowAPPPAA73znO1m3bh1nnHEGCxcu5P777+fyyy9nzJgxzJ07lwsuuIAnnniCc889l7FjxzJmzBguvfRSbrvtNtasWcP555/P+eef356/OEm5ct+f2s1QKGnUli5dytVXX83EiRM577zzuOeee5g5cybLli3j61//Og8//DBnnnkm3/nOd1i+fDmLFy/e+Yb7xBNP5KCDDuLSSy/ly1/+Mr29vbz85S/nAx/4AD/96U93LgV89NFH+Yd/+AdmzpzJF77wBb71rW9x+umn71bH+vXrue666/jGN77B9ddfz5e//GXuu+8+vvjFL7Jo0SKeffZZrr/+enp7e3nXu97Fgw8+yMknn8ySJUs455xz2Lp1q4GwSxVljE6cOJGrr76a3/3ud7z1rW/liCOO4OMf/zg333wz06ZN4zOf+Qxf+9rX2Lp1K6985Ss555xz+PGPf8yaNWs4/fTTufHGGw2EUok4E6h2MxRKGrVp06Zx9tlns/fee/OrX/2Kgw46CID999+fcePGMXnyZObNm8f48eOZOnXqzj1a48aN23nvwQcfzJIlS9ixYwdHHHEEAK961asYO7byz9PMmTO56KKL6OvrY/ny5Rx88MHPq+OAAw4AYPLkybz0pS+lp6dn59fr7e1l3Lhx/M3f/A19fX0sW7aMbdu2AfDe976XE044gdtuuy3bvyjlpihj9JBDDqGnp4dp06YxefJkVq9ezYoVKzjrrLOAygzjYYcdxumnn84111zD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\n",
      "text/plain": [
       "<Figure size 1080x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,6))\n",
    "plt.errorbar(np.log(ridge5.lambda_path_), -ridge5.cv_mean_score_, color='r', linestyle='None', marker='o',\n",
    "             markersize=5, yerr=ridge5.cv_standard_error_, ecolor='lightgrey', capsize=4)\n",
    "\n",
    "for ref, txt in zip([ridge5.lambda_best_, ridge5.lambda_max_], ['Lambda best', 'Lambda max']):\n",
    "    plt.axvline(x=np.log(ref), linestyle='dashed', color='lightgrey')\n",
    "    plt.text(np.log(ref), .95*plt.gca().get_ylim()[1], txt, ha='center')\n",
    "\n",
    "plt.xlabel('log(Lambda)')\n",
    "plt.ylabel('Mean-Squared Error');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "96006.84514850576"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# MSE for lambda with best CV performance\n",
    "pred = ridge5.predict(X_test, lamb=ridge5.lambda_max_)\n",
    "mean_squared_error(y_test, pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fit model to full data set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=0, cut_point=1.0, fit_intercept=True, lambda_path=None,\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=10, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ridge6= gln.ElasticNet(alpha=0, scoring='mean_squared_error', n_splits=10)\n",
    "ridge6.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat           -0.681594\n",
       "Hits             2.772311\n",
       "HmRun           -1.365704\n",
       "Runs             1.014812\n",
       "RBI              0.713030\n",
       "Walks            3.378558\n",
       "Years           -9.066826\n",
       "CAtBat          -0.001200\n",
       "CHits            0.136102\n",
       "CHmRun           0.697992\n",
       "CRuns            0.295890\n",
       "CRBI             0.257072\n",
       "CWalks          -0.278966\n",
       "PutOuts          0.263887\n",
       "Assists          0.169878\n",
       "Errors          -3.685656\n",
       "League_N        53.209503\n",
       "Division_W    -122.834334\n",
       "NewLeague_N    -18.102528\n",
       "dtype: float64"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# These are not really close to the ones in the book.\n",
    "pd.Series(ridge6.coef_path_[:,ridge6.lambda_max_inx_], index=X.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.6.2 The Lasso"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Scikit-learn"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "For both __glmnet__ in R and sklearn __Lasso()__ function the standard L1 penalty is:\n",
    "### $$ \\lambda |\\beta|_1 $$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "lasso = Lasso(max_iter=10000)\n",
    "coefs = []\n",
    "\n",
    "for a in alphas*2:\n",
    "    lasso.set_params(alpha=a)\n",
    "    lasso.fit(scale(X_train), y_train)\n",
    "    coefs.append(lasso.coef_)\n",
    "\n",
    "ax = plt.gca()\n",
    "ax.plot(alphas*2, coefs)\n",
    "ax.set_xscale('log')\n",
    "ax.set_xlim(ax.get_xlim()[::-1])  # reverse axis\n",
    "plt.axis('tight')\n",
    "plt.xlabel('alpha')\n",
    "plt.ylabel('weights')\n",
    "plt.title('Lasso coefficients as a function of the regularization');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LassoCV(alphas=None, copy_X=True, cv=10, eps=0.001, fit_intercept=True,\n",
       "    max_iter=10000, n_alphas=100, n_jobs=1, normalize=False,\n",
       "    positive=False, precompute='auto', random_state=None,\n",
       "    selection='cyclic', tol=0.0001, verbose=False)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lassocv = LassoCV(alphas=None, cv=10, max_iter=10000)\n",
    "lassocv.fit(scale(X_train), y_train.values.ravel())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "30.013822564464284"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lassocv.alpha_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "102924.90954696963"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lasso.set_params(alpha=lassocv.alpha_)\n",
    "lasso.fit(scale(X_train), y_train)\n",
    "mean_squared_error(y_test, lasso.predict(scale(X_test)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat            0.000000\n",
       "Hits             0.000000\n",
       "HmRun            2.154219\n",
       "Runs             0.000000\n",
       "RBI             30.835560\n",
       "Walks          104.071528\n",
       "Years           -0.000000\n",
       "CAtBat           0.000000\n",
       "CHits            0.000000\n",
       "CHmRun           0.000000\n",
       "CRuns          132.858095\n",
       "CRBI             0.000000\n",
       "CWalks           0.000000\n",
       "PutOuts          1.896185\n",
       "Assists        -51.058752\n",
       "Errors          76.779641\n",
       "League_N         0.000000\n",
       "Division_W       0.000000\n",
       "NewLeague_N      0.000000\n",
       "dtype: float64"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Some of the coefficients are now reduced to exactly zero.\n",
    "pd.Series(lasso.coef_, index=X.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### python-glmnet"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=1, cut_point=1.0, fit_intercept=True,\n",
       "      lambda_path=array([1.00000e+10, 7.56463e+09, ..., 1.32194e-02, 1.00000e-02]),\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=10, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lasso2 = gln.ElasticNet(alpha=1, lambda_path=grid, scoring='mean_squared_error', n_splits=10)\n",
    "lasso2.fit(X_train, y_train.values.ravel())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "l1_norm = np.sum(np.abs(lasso2.coef_path_), axis=0)\n",
    "\n",
    "plt.figure(figsize=(10,6))\n",
    "plt.plot(l1_norm, lasso2.coef_path_.T)\n",
    "plt.xlabel('L1 norm')\n",
    "plt.ylabel('Coefficients');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Let glmnet() create a grid to use in CV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=1, cut_point=1.0, fit_intercept=True, lambda_path=None,\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=10, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lasso3 = gln.ElasticNet(alpha=1, scoring='mean_squared_error', n_splits=10)\n",
    "lasso3.fit(X_train, y_train.values.ravel())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA4UAAAFuCAYAAAA2zL3IAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3X2cnFV9///X7pLdZDc3hmSzQQKNsXiKWhrwJlpB04UaF7F+y6MWEEql3lBaELypgAhFfoiF4hcD1jsQotz5FQvWH35DVCItRAzaktaAnKI0IpBslhgSsptsks1+/5hJ3MTszjXZmbmumev1fDx4ZOaaM3N9ZvckzHvOuc5pGh4eRpIkSZKUT81pFyBJkiRJSo+hUJIkSZJyzFAoSZIkSTlmKJQkSZKkHDMUSpIkSVKOHZR2AdUWQmgDXgesBYZSLkeSJEmSaq0FOAT4cYxxcN8HGz4UUgiED6ZdhCRJkiSl7DjgoX0P5iEUrgW4/fbbmT17dtq1SJIkSVJNrVu3jtNPPx2K2WhfeQiFQwCzZ89mzpw5adciSZJU9zZs2ADAjBkzUq5E9c6+VHP7vZzOhWYkSZJUlk2bNrFp06a0y1ADsC9lg6FQkiRJknLMUChJkiRJOWYolCRJkqQcMxRKkiRJUo7lYfVRSZIkVdC8efPSLkENwr6UDY4USpIkSVKOGQolSZJUlueff57nn38+7TLUAOxL2WAolCRJUlk2b97M5s2b0y5DDcC+lA2GQkmSJEnKMUOhJEmSJOWYoVCSJEmScswtKSRJklSW5mbHFVQZjdCXent76evrG/Xxzs5Ourq6alhR+QyFkiRJKsvcuXPTLkENohH6UldX157Q99RTTwH1t/9i/UdzSZIkSdIBMxRKkiSpLOvXr2f9+vVpl6EGYF/KBkOhJEmSyrJlyxa2bNmSdhlqAPalbDAUSpIkSVKOGQolSZIkKccMhZIkSZKUY4ZCSZKkOrdy5Uo+9KEPVez1uru7GRwcHPXxXbt28Z73vKdi51N2ZLkv3X333Vx77bXjque2224b1/MblfsUSpIkqSyHHXYYBx3kx0iNX6370he+8AXOOOOMxO0bYWP6JPzbLEmS1KDuu+8+br/99j33Fy9ezJNPPsmXv/xlJkyYwLp16zj11FP50Y9+xBNPPMGZZ57Ju9/9bgAuu+wynn32WWbMmMHVV1/N0NAQH/3oR9m8eTOHH374ntd85JFH+NznPgfAtm3buPrqq3nZy1625/G7776bH/zgB2zbto2+vj7OPPNM7r//fp588kk+9rGPccIJJ3Dbbbfx3e9+l507dzJlyhRuuOEG7rrrLv7jP/6Dz3zmM1x44YUcddRRnH766TX6yWlfWehLAKtWreIv//Iv2bJlC+eddx4LFy7kkUce4brrrqOlpYXDDjuMK664gmeeeYaLL76Ygw46iJaWFq655hruvvtuNm3axOWXX87ll1+e6H03wsb0SRgKJUmSGtSaNWv48pe/zKRJk7jssst46KGH6OrqYt26dXzrW9/iscce4/zzz+d73/sevb29nHvuuXs+yJ922mnMnz+fa665hm984xs0Nzfzile8gg996EMsX76cH/7whwA8+eST/OM//iNdXV188Ytf5L777uOcc87Zq47+/n5uvvlmvvOd77BkyRK+8Y1vsHLlSr72ta/R3d3NCy+8wJIlS2hubua9730vP/3pTzn99NNZsWIFF110ETt27DAQpiwrfWnSpEl8+ctf5te//jXvete7OO6447j00ku54447mDFjBp/97Ge555572LFjB6961au46KKL+MlPfsKmTZs455xzuO222xIHwjwxFEqSJDWoGTNmcOGFF9LR0cFTTz3F/PnzATjiiCOYMGECU6ZM4fDDD6e1tZVp06btufZrwoQJe9oec8wxrFixgl27dnHccccBMHfuXJqbC0tTdHV18alPfYr29nZ6e3s55phjfquOI488EoApU6bw8pe/nKampj3na25uZsKECXz4wx+mvb2ddevWsXPnTgA+8IEPcMopp3D33XdX9welkrLSl17zmtfQ1NTEjBkzmDJlChs3bmT9+vVccMEFQGGE8U1vehPnnHMON954I+973/uYMmVKRa+TbEQVD4UhhAnAzcBcoA24Msb47eJj7wbOizG+sXj//cDZwM5iu3tDCDOBO4BJwHPAWTHGgXLaVvo9SZIk1ZsXX3yR66+/ngceeACAs846i+HhYQCamprGfO6OHTv42c9+xpFHHslPfvITjjjiCHbs2MGqVas44YQT+PnPf74nuH3iE5/g+9//PpMnT+bCCy/cc46RxjrfE088wfe//33uuusutm7dysknn8zw8DDbt2/nqquu4oorruDyyy/n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\n",
      "text/plain": [
       "<Figure size 1080x432 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,6))\n",
    "plt.errorbar(np.log(lasso3.lambda_path_), -lasso3.cv_mean_score_, color='r', linestyle='None', marker='o',\n",
    "             markersize=5, yerr=lasso3.cv_standard_error_, ecolor='lightgrey', capsize=4)\n",
    "\n",
    "for ref, txt in zip([lasso3.lambda_best_, lasso3.lambda_max_], ['Lambda best', 'Lambda max']):\n",
    "    plt.axvline(x=np.log(ref), linestyle='dashed', color='lightgrey')\n",
    "    plt.text(np.log(ref), .95*plt.gca().get_ylim()[1], txt, ha='center')\n",
    "\n",
    "plt.xlabel('log(Lambda)')\n",
    "plt.ylabel('Mean-Squared Error');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "101294.32852317697"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pred = lasso3.predict(X_test, lamb=lasso3.lambda_max_)\n",
    "mean_squared_error(y_test, pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fit model on full dataset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ElasticNet(alpha=1, cut_point=1.0, fit_intercept=True,\n",
       "      lambda_path=array([1.00000e+10, 7.56463e+09, ..., 1.32194e-02, 1.00000e-02]),\n",
       "      max_iter=100000, min_lambda_ratio=0.0001, n_jobs=1, n_lambda=100,\n",
       "      n_splits=10, random_state=None, scoring='mean_squared_error',\n",
       "      standardize=True, tol=1e-07, verbose=False)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "lasso4 = gln.ElasticNet(alpha=1, lambda_path=grid, scoring='mean_squared_error', n_splits=10)\n",
    "lasso4.fit(X, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AtBat           -1.560098\n",
       "Hits             5.693168\n",
       "HmRun            0.000000\n",
       "Runs             0.000000\n",
       "RBI              0.000000\n",
       "Walks            4.750540\n",
       "Years           -9.518024\n",
       "CAtBat           0.000000\n",
       "CHits            0.000000\n",
       "CHmRun           0.519161\n",
       "CRuns            0.660407\n",
       "CRBI             0.391541\n",
       "CWalks          -0.532687\n",
       "PutOuts          0.272620\n",
       "Assists          0.174816\n",
       "Errors          -2.056721\n",
       "League_N        32.109569\n",
       "Division_W    -119.258342\n",
       "NewLeague_N      0.000000\n",
       "dtype: float64"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# These are not really close to the ones in the book.\n",
    "pd.Series(lasso4.coef_path_[:,lasso4.lambda_max_inx_], index=X.columns)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Lab 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.7.1 Principal Components Regression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scikit-klearn does not have an implementation of PCA and regression combined like the 'pls' package in R.\n",
    "https://cran.r-project.org/web/packages/pls/vignettes/pls-manual.pdf"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(19, 19)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.198290</td>\n",
       "      <td>-0.383784</td>\n",
       "      <td>0.088626</td>\n",
       "      <td>0.031967</td>\n",
       "      <td>0.028117</td>\n",
       "      <td>-0.070646</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.195861</td>\n",
       "      <td>-0.377271</td>\n",
       "      <td>0.074032</td>\n",
       "      <td>0.017982</td>\n",
       "      <td>-0.004652</td>\n",
       "      <td>-0.082240</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.204369</td>\n",
       "      <td>-0.237136</td>\n",
       "      <td>-0.216186</td>\n",
       "      <td>-0.235831</td>\n",
       "      <td>0.077660</td>\n",
       "      <td>-0.149646</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.198337</td>\n",
       "      <td>-0.377721</td>\n",
       "      <td>-0.017166</td>\n",
       "      <td>-0.049942</td>\n",
       "      <td>-0.038536</td>\n",
       "      <td>-0.136660</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.235174</td>\n",
       "      <td>-0.314531</td>\n",
       "      <td>-0.073085</td>\n",
       "      <td>-0.138985</td>\n",
       "      <td>0.024299</td>\n",
       "      <td>-0.111675</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0         1         2         3         4         5\n",
       "0  0.198290 -0.383784  0.088626  0.031967  0.028117 -0.070646\n",
       "1  0.195861 -0.377271  0.074032  0.017982 -0.004652 -0.082240\n",
       "2  0.204369 -0.237136 -0.216186 -0.235831  0.077660 -0.149646\n",
       "3  0.198337 -0.377721 -0.017166 -0.049942 -0.038536 -0.136660\n",
       "4  0.235174 -0.314531 -0.073085 -0.138985  0.024299 -0.111675"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pca = PCA()\n",
    "X_reduced = pca.fit_transform(scale(X))\n",
    "\n",
    "print(pca.components_.shape)\n",
    "pd.DataFrame(pca.components_.T).loc[:4,:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above loadings are the same as in R."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(263, 19)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "      <th>3</th>\n",
       "      <th>4</th>\n",
       "      <th>5</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>-0.009649</td>\n",
       "      <td>1.870522</td>\n",
       "      <td>1.265145</td>\n",
       "      <td>-0.935481</td>\n",
       "      <td>1.109636</td>\n",
       "      <td>1.211972</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.411434</td>\n",
       "      <td>-2.429422</td>\n",
       "      <td>-0.909193</td>\n",
       "      <td>-0.264212</td>\n",
       "      <td>1.232031</td>\n",
       "      <td>1.826617</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3.466822</td>\n",
       "      <td>0.825947</td>\n",
       "      <td>0.555469</td>\n",
       "      <td>-1.616726</td>\n",
       "      <td>-0.857488</td>\n",
       "      <td>-1.028712</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-2.558317</td>\n",
       "      <td>-0.230984</td>\n",
       "      <td>0.519642</td>\n",
       "      <td>-2.176251</td>\n",
       "      <td>-0.820301</td>\n",
       "      <td>1.491696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1.027702</td>\n",
       "      <td>-1.573537</td>\n",
       "      <td>1.331382</td>\n",
       "      <td>3.494004</td>\n",
       "      <td>0.983427</td>\n",
       "      <td>0.513675</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "          0         1         2         3         4         5\n",
       "0 -0.009649  1.870522  1.265145 -0.935481  1.109636  1.211972\n",
       "1  0.411434 -2.429422 -0.909193 -0.264212  1.232031  1.826617\n",
       "2  3.466822  0.825947  0.555469 -1.616726 -0.857488 -1.028712\n",
       "3 -2.558317 -0.230984  0.519642 -2.176251 -0.820301  1.491696\n",
       "4  1.027702 -1.573537  1.331382  3.494004  0.983427  0.513675"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print(X_reduced.shape)\n",
    "pd.DataFrame(X_reduced).loc[:4,:5]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above principal components are the same as in R."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([38.31, 60.15, 70.84, 79.03, 84.29, 88.63, 92.26, 94.96, 96.28,\n",
       "       97.25, 97.97, 98.64, 99.14, 99.46, 99.73, 99.88, 99.95, 99.98,\n",
       "       99.99])"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Variance explained by the principal components\n",
    "np.cumsum(np.round(pca.explained_variance_ratio_, decimals=4)*100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 10-fold CV, with shuffle\n",
    "n = len(X_reduced)\n",
    "kf_10 = KFold(n_splits=10, shuffle=True, random_state=1)\n",
    "\n",
    "regr = LinearRegression()\n",
    "mse = []\n",
    "\n",
    "# Calculate MSE with only the intercept (no principal components in regression)\n",
    "score = -1*cross_val_score(regr, np.ones((n,1)), y.ravel(), cv=kf_10, scoring='neg_mean_squared_error').mean()    \n",
    "mse.append(score)\n",
    "\n",
    "# Calculate MSE using CV for the 19 principle components, adding one component at the time.\n",
    "for i in np.arange(1, 20):\n",
    "    score = -1*cross_val_score(regr, X_reduced[:,:i], y.ravel(), cv=kf_10, scoring='neg_mean_squared_error').mean()\n",
    "    mse.append(score)\n",
    "    \n",
    "plt.plot(mse, '-v')\n",
    "plt.xlabel('Number of principal components in regression')\n",
    "plt.ylabel('MSE')\n",
    "plt.title('Salary')\n",
    "plt.xlim(xmin=-1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above plot indicates that the lowest training MSE is reached when doing regression on 18 components."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 106.36859204,  -21.60350456,   24.2942534 ,  -36.9858579 ,\n",
       "        -58.41402748,   62.20632652,   24.63862038,   15.82817701,\n",
       "         29.57680773,   99.64801199,  -30.11209105,   20.99269291,\n",
       "         72.40210574, -276.68551696,  -74.17098665,  422.72580227,\n",
       "       -347.05662353, -561.59691587,  -83.25441536])"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "regr_test = LinearRegression()\n",
    "regr_test.fit(X_reduced, y)\n",
    "regr_test.coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Fitting PCA with training data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAY4AAAEPCAYAAABV6CMBAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzt3Xl8VNX5+PHPZCeQCWsSICwK+Cgo+6qAaLCIWG1dURRBNpcWsVZtLa31W1urP5fWXVlEBAT3uqFYREUEEQQFxUdZLER2hLAmZJnfH/cGhpCQTJJZknnerxcvZu499865dybzzDn3nOd6fD4fxhhjTEXFhLsCxhhjahYLHMYYYwJigcMYY0xALHAYY4wJiAUOY4wxAbHAYYwxJiBx4a6AMTWdiPQG7gMa4fwY2wT8XlW/OcE204DVqvpgSCppTDWyFocxVSAiicDbwG2q2lFVTwdmAnNFJDa8tTMmOKzFYUzVJAP1gXp+y2YCe4FYEXkY6A2kAB5gtKou8t+BiFwPjAMSgIbAP1X1KREZAYwC6gI5QAHwkqpOcrebCDRS1VuDd3jGHM9aHMZUgaruBu4A3hOR9SLyAjAS+C/QDWgG9FHV9sDzwB/8txeResAY4AJV7QJcCTzgV6QDMEBVzwGecMsiIjE4QeXpIB6eMaWywGFMFanqw0A6MB7YAtwJrAC+BSYC40TkQeAyjm2ZoKr7gQuBISLyN+BPJcp8rap73cdvAeki0gkYBGxQVQ3agRlTBgscxlSBiJwlIrer6j5VfVtV78BpJfiAXwHvuEX/g9M68JTYPhNYCbQCPsUJNP72Fz9Q1ULgGeB695+1NkxYWOAwpmp2ABNFpK/fsqZAKjAUeEtVnwKW4QSSkhfMu7v7uBeYh9P64AQX1icDv8bpBnu9mo7BmIBY4DCmClT1e5yA8A/3Gse3wEs41zluBQaIyCrgS2AdcJJ7faLYPCAbUGAN0BInkLQt4/W24wShF1U1PzhHZcyJeSytujE1h4g0Br4A+qvqpnDXx0Qna3EYU0OIyBicVsn/s6BhwslaHMYYYwJiLQ5jjDEBscBhjDEmILU+5YibS6gHzsSswjBXxxhjaopYnKHlX6hqnv+KWh84cILGwnBXwhhjaqh+OJNTj4iGwLEFYObMmWRkZIS7LsYYUyNs3bqVYcOGgfsd6i8aAkchQEZGBpmZmeGuizHG1DTHdfHbxXFjjDEBscBhjDEmIBY4jDHGBMQChzHGmIBEw8XxSrng3wv5dsve45a3b+rl3Vv6haFGxhgTGazFUYauLesTH3vMPXeIj/XQtVWDMNXIGGMigwWOMozPakeM59jAEevxMD6r1NskGGNM1LDAUYY0bxKXd8s8cp/P+FgPl3VvQVpKUljrZYwx4WaB4wTGZ7WjuNFhrQ1jjHFY4DiBNG8SkpECwGXdMq21YYwxWOAo1y/apwMw8qyTwlwTY4yJDBY4ytE2zWlxFBTZnRKNMQYscJQrI9Xpntq2NzfMNTHGmMhggaMc6SkWOIwxxp8FjnKkeRMBCxzGGFPMAkc5kuJjqZ8cz7a9eeUXNsaYKGCBowLSU5KsxWGMMS4LHBWQ5k1k2z5rcRhjDFjgqJB0bxLbcqzFYYwxEIS06iISD0wFWgOJwL2q+qa77hFAVfVp9/kYYBxQ4JZ7W0QaA7OAOsBmYKSqHgykbHUfU4Y3iR378ygs8hEb4yl/A2OMqcWC0eK4Btilqv2AwcDjItJEROYCFxUXEpEMYDxwFjAIuE9EEoG/ALPc7VcA4wIpG4TjId2bSGGRj10HrLvKGGOCETheBv7s97wAqAf8FXjBb3lPYJGq5qlqDrAW6Aj0Bd5zy8wFBgZYttqled25HDkWOIwxptq7qlR1P4CIpACvABNVdQOwQUQG+xX1Ajl+z/cBqSWWl7asvLLVLsN7dBLgGcF5CWOMqTGCcnFcRFoAC4AXVHVWGcX2Ail+z1OAPSWWl7asvLLVLr04cOyzC+TGGFPtgUNE0oF5wJ2qOvUERZcC/UQkSURSgdOA1cAi4AK3zGBgYYBlq13jegnEeLCRVcYYQ3BaHHcBDYA/i8hH7r86JQup6lbgUZwv+w+BP6lqLnAvMFREFgF9gMcDKRuE4yEuNobG9RJt9rgxxgAen692pwsXkdbAhvnz55OZmVnp/fzysU9pVC+BaSN7VlvdjDEmUmVnZ5OVlQVwkqr+6L/OJgBWULrXWhzGGAMWOCoszWv5qowxBixwVFiGN4mfDxwmr6Aw3FUxxpiwssBRQenufTl2WLJDY0yUs8BRQWleuxOgMcaABY4KOzp73FocxpjoZoGjgtKtxWGMMYAFjgprkBxPQmwMWy1wGGOinAWOCvJ4PKR5E9luXVXGmChngSMA6TaXwxhjLHAEwpk9boHDGBPdLHAEIC0lyUZVGWOingWOAGSkJrE/r4D9eQXhrooxxoSNBY4AFM8e327dVcaYKGaBIwDpKc5cDhuSa4yJZhY4ApCe6gQOG5JrjIlmFjgCYLPHjTHGAkdA6iXGUTch1rqqjDFRzQJHgNK9SdZVZYyJahY4AmSzx40x0c4CR4DSvYls22eBwxgTveKCsVMRiQemAq2BROBe4FtgGuADVgM3q2qRiNwNDAEKgAmqulRE2la1bDCOC4pbHHn4fD48Hk+wXsYYYyJWsFoc1wC7VLUfMBh4HHgYmOgu8wAXi0hX4GygFzAUeMLdvkplg3RMgBM4DhcUsedgfjBfxhhjIlawAsfLwJ/9nhcA3YCP3edzgYFAX2CeqvpUdSMQJyJNqqFs0BwZkmvdVcaYKBWUwKGq+1V1n4ikAK8AEwGPqvrcIvuAVMAL5PhtWry8qmWDpjjtyNYcCxzGmOgUtIvjItICWAC8oKqzAP/rDinAHmCv+7jk8qqWDZriFocNyTXGRKugBA4RSQfmAXeq6lR38QoRGeA+HgwsBBYBg0QkRkRaAjGqurMaygZNmtvisCG5xphoFZRRVcBdQAPgzyJSfK3jFuBREUkA1gCvqGqhiCwEFuMEsZvdsrcBkypbNkjHBEBiXCwNkuPtGocxJmp5fD5f+aVqMBFpDWyYP38+mZmZ1bLP8//1CZkNkpl8Xfdq2Z8xxkSa7OxssrKyAE5S1R/919kEwEpI9yax3VocxpgoZYGjEuze48aYaGaBoxLSvUns2JdHQWHQJqgbY0zEssBRCeneJIp8sOvA4XBXxRhjQs4CRyXYDZ2MMdHMAkcl2OxxY0w0s8BRCRlH8lXZ7HFjTPSxwFEJjeolEuOB7dZVZYyJQhY4KiE2xkOTFBuSa4yJThY4Kindm8RWS3RojIlCFjgqKd2bZF1VxpioZIGjkmz2uDEmWlngqKT0lCR2H8wnN78w3FUxxpiQssBRSempzpDcHTYk1xgTZSxwVJLNHjfGRCsLHJV0ZPa4BQ5jTJSxwFFJ6SnFLQ7rqjLGRBcLHJVUPzmehLgYG5JrjIk6FjgqyePx2JBcY0xUssBRBekpSXaNwxgTdeKCtWMR6QXcr6oDRKQr8DSQB6wEblHVIhG5GxgCFAATVHWpiLQFpgE+YDVwc6Blg3VMJaWnJrFm895QvZwxxkSEoLQ4ROQOYDKQ5C56FufLvh+QA1ztBpOzgV7AUOAJt+zDwES3rAe4OJCywTiesqSnJFlXlTEm6gSrq2odcInf80xV/cx9vAjo6/6bp6o+Vd0IxIlIE6Ab8LFbdi4wMMCyIZPuTeTA4UL25eaH8mWNMSasghI4VPVVwP/bdL2InO0+/iVQF/DitD6K7QNSAY+q+kosC6RsyGSk2pBcY0z0CdXF8ZHAH0XkHWA7sBPYC6T4lUkB9gBFpSwLpGzIpLlzOWxIrjEmmoQqcAwBrlfVIUAj4AOcLqtBIhIjIi2BGFXdCawQkQHudoOBhQGWDZni2ePb9lngMMZEj6CNqirhB+BdETkILFDVdwFEZCGwGCeA3eyWvQ2YJCIJwBrgFVUtrGjZEB0PcDRf1dYc66oyxkQPj8/nK79UDSYirYEN8+fPJzMzs9r3f8bd73Npt0z+elGHat+3McaES3Z2NllZWQAnqeqP/utsAmAVpXkT2W5dVcaYKGKBo4rSvUlszbHAYYyJHhY4qijDm2TDcY0xUcUCRxWleZPYvi+X2n6tyBhjilngqKJ0byL5hT5+PnA43FUxxpiQsMBRRRlemz1ujIkuFjiqKK04cNjIKmNMlLDAUUXFs8ct7YgxJlpY4Kii4nxVNnvcGBMtLHBUUUJcDI3qJlhXlTEmaljgqAZp3iTrqjLGRA0LHNUg3Zto9x43xkQNCxzVwGaPG2OiSaUCh4gkVndFarI0bxI79+dRUFhUfmFjjKnhThg4RGSO3+Pb/FbNDVqNaqB0byI+H+zYb60OY0ztV16LI83v8RC/x54g1KXGSk+x2ePGmOgRSFeVf7CwjH5+MlKLA4ddIDfG1H7lBQ5fGY+NnzSbPW6MiSLl3XO8g4jMwmlt+D9uH/Sa1SCN6iYSG+OxIbnGmKhQXuC4wu/x02U8jnqxMR7SUhLtGocxJiqcMHCo6sci0klVvxKRBGAMkAdMLW/HItILuF9VB4hIZ5xgUwB8D4xW1SIRGQOMc5ffq6pvi0hjYBZQB9gMjFTVg4GUrcyJqKo0b5Jd4zDGRIXyhuP+DnhWROKA/wecB5wBPFLOdncAk4Ekd9HdwP+pal8gERgiIhnAeOAsYBBwnzs/5C/ALFXtB6wAxgVSNsDjrzbpKYkWOIwxUaG8i+ODgTOBIuBqnF/0twA9ytluHXCJ3/MVQEMR8QApQD7QE1ikqnmqmgOsBToCfYH33O3mAgMDLBsWGak2e9wYEx3KCxxFqloIdAbWq+pud/kJ53Go6qs4waHYD8CjwBogHfgI8AI5fmX2Aakllpe2rLyyYZHuTSLnUD65+YXhqoIxxoREufM4ROQUYCTwlvu8AxDot+O/gX6qeiowHXgI2IvT+iiWAuwpsby0ZeWVDYu0FGdIrnVXGWNqu/ICx0TgBZwZ5P8SkbNxuoR+H+Dr/IzzJQ/ORewGwFKgn4gkiUgqcBqwGlgEXOCWHQwsDLBsWKTbvceNMVGivMBxI/ANcBCnq+kGnC/nsQG+zmhgtoh8DNwE3KWqW919LgQ+BP6kqrnAvcBQEVkE9AEeD6RsgPWqNjZ73BgTLcqbx9EdZ6jrTOAzAshRpao/Ar3dx5/ijIgqWWYSMKnEsm3A+VUpGw5H81VZ4DDG1G4nbHGoakfg1zjDav+A86t+naq+H4K61SjeOnEkxsVY4DDG1HrltThQ1dU4QQMR6Y8zh6KFqvYOduVqEo/HY0NyjTFRodzAASAiXpyWx1VAXWBGMCtVU6Wn2OxxY0ztd8LAISKX4wSLlsBrwA3utQtTijRvIqt/yim/oDHG1GDljaqaA5yKM4HvDOAfIjLLzZJrSii+97jPZxnojTG1V3ldVeeEpBa1RLo3iUP5hezLK8CbFB/u6hhjKumCfy/k2y17j1vevqmXd2/pF4YaRZZys+OGqiK1gf8NnSxwGFNzdW1Znx+27yO/8GjvQXysh66tGoSxVpEjkFvHmnIUzx7fmmMjq4ypyX5zTls8JaatxXo8jM9qG6YaRZYKjaoyFZPhtUmAxtRUeQWFLFn/M/O+2cp/12zjcGHRkXXxsR4u696CtJSkE+wheljgqEbFXVXb9lngMKYmyDmUz0e6nXnfbuNj3cH+vAKSE2Lp364JvU9uyN/fXUN+oY+CQh9De2SGu7oRwwJHNUpOiCMlKY5tORY4jAmnE13cnnxddz74dhsffLuNJet3UVDko3G9RH7ZqSnntU/nzDaNSYqPBWDt9v3M/HwjsTEebp61gtlje9M0tU6oDyfiWOCoZsVDco0x4VPaxe1YD2zde4gz//khACc3qcvofidzXvt0urSoT0zM8an4xme14/vt+xnb/2QmzF7J0GeX8OKY3jSrH93BwwJHNUv3JllXlTFhNj6rHS8vzwaOBo5CHzSvX4ex/dtwXvt02jSpV+5+0rxJvDSuDwDTR/XkuilLGfrsEmaPje7gYaOqqlmaN9G6qowJswZ1E2ji3lwNIDYGLuvWnLd+248bzm5ToaBRUteWDZg+qie7Dxxm6LNL2LznUHVWuUaxwFHN0r1JbN+XR1GRzR43JhwKi3z8/uWvyN59iDi3+yk+JoY7zj+1yvvuUiJ4/BSlwcO6qqpZhjeJgiIfPx88TON6ieVvYEwEqqkzp30+HxPfWMV/Vm7m9kHClj2HmLl0Y7UOpS0OHsOnLGXos4uZPbYPzaOs28paHNUs3Wv3Hjc1X9eW9YmPPfZicaTPnPb5fNz7zhpeXLqJmwa04eZz2jI+qx09Wjes9ol7XVo24IXRvdhzMJ+hzy4me/fBat1/pLPAUc3SbBKgqeFyDubTMbM+RUXHLo/0mdOP/PcHpny6gRFntub2QQIcvbgdjIl7nVvUZ8YoJ3hcNWlJVAUP66qqZkdnj9uQXFMzHDxcwBc/7uaztTv5bN0uVm/Owedzhq8Wi40homdOP/PxOh6d/wNXdM/kLxe2x+Op8F2uq6STGzyumfL5kdFWmQ2SQ/La4WSBo5oVj+SwFocJpxNdo3j95jNZuXEPi9btYvG6nazctIf8Qh/xsR66tGzAhKxTOLNtI5qmJpH10MfkFRRRWARtm9QNw5GU74XFP3Lf3O+4sGNT7rukY6nzMYKpU4v6zBzdi2smf35knkeLhrU7eFjgqGbxsTE0rpdggcOEVVkT4HYfzKPTPfPIzS8ixgNnNE9lVN+TOattI7q3akidhNhj9nN5t0xmLt1Iekoi97z9LanJ8fy6S+Sk3nh1eTZ//s83DDwtjUeu7ExsiINGsY6Z9ZnhFzxmj63dwSNogUNEegH3q+oAEZkNZLirWgNLVHWoiNwNDAEKgAmqulRE2gLTcGburAZuVtWiQMoG65gqKt1mj5swK2sCXHJ8HIN6NOWsto3peVJDUuucOP1/8czpBy/rxJ2vfs1tL31FjMfDxZ2bB/kIyjd31RZuf+UrzmrbiMev7kp8bHgv2XbMrM/M0b0ZNnkJ5zz4EQWlDMmP9FFpFRWUwCEidwDXAgcAVHWou7wBsAC4VUS6AmcDvYAWwKtAD+BhYKKqfiQiTwMXi8j/KloWeD0YxxQIJ3BYi8OEz6H8QhJiY8grcH5HxcZ4+HWXZjx4eeeA9uM/c3rKiO5cP+0Lbp2zEo/Hw0WdmlV7vStqwXfbGT97BV1aNmDS8O5HckuF2xmZqcwc3ZtLn1p03LpQjkoL9nDqYIXodcAlpSy/B3hMVbcAfYF5qupT1Y1AnIg0AboBxTeQmgsMDLBs2KV7Ey1wmLBZ9uPP/PrJz4iJ4ciQ2vgYT5UnwCUnxDF1RA+6t27IhNkreOurzdVR3YAtXreLG2YsRzJSmDqiB8kJkdXjfkZmKpOv63Hc8lCOSgv2cOqgBA5VfRXI918mImlAFk7XEoAXyPErsg9IBTyq6iuxLJCyYZeWksTO/YfJLwx7r5mJMm9+tZmrJ39Oap143ri5L1d2b4HHU30jopIT4nhuRA+6t2rIhDkreefrLdVQ64r7cuNuRj3/BS0bJjP9+l7ldrWFS/9TmjD49Iwjzz1Av1OahGxU2jW9W1Gyp6w6A1coOwUvA2apaqH7fC+Q4rc+BdgDFJWyLJCyYZeR6nw4duyz6xwmNHw+H49/+APjX1xB58z6vHbjmZzUuG5QJsDVTYzjuZE96NqyPuNnr2DuqtAEj2825zBi6lKapCQyY3QvGtZNCMnrVtY9F3UgMc75ivUBH3y7jSufWcxn63bi8wUnJdG6Hfv542uruPiJRRQW+Y7cw7C6b0QVysAxEKc7qdgiYJCIxIhISyBGVXcCK0RkgFtmMLAwwLJhZ7PHTSgdLiji9le+5sF53/Orzs14YXRPGrhfqsGaAOcEj550blGf3764gvdWBzd4rN2+n+FTllIvMY6Zo3sduU1zJEvzJnF5t0w8HriqZwvu/mV7Nuw8wNWTPufKZ5bw6Q/VE0B8Ph+fr9/F6OeXkfXQx7z6ZTaXdG3OnLG9SXADV3V3k4Wyc1CA9cVPVHW5iCwEFuMEsJvdVbcBk0QkAVgDvKKqhRUtG5IjKUfxH6kFDhNsOQfzuWHGchav38UtWe2YMLBdyCa/1UuMY9rIHlw3dSm/mbWCJ4Z5GNQho/wNK6Csi7ttmtStURPsikel3XreKaSlJHFVz5a8tGwTTy5YxzVTPqdbqwaMz2pH/3aNA37fCgqLeO+brUz6ZD1fZefQIDme8VntGN6n1ZE8ecXDqat78qYnWE2mSCEirYEN8+fPJzMzNOPPd+7Po/u9/+Weizpw3ZmtQ/KaJvps3HWQkdOWsvHng9x/aUcu6Rqe+RX7cvMZPnUpq7JzeHJYV35RDcFj4uurmLNs0zHzUOJiPAzt2ZJ7f3V6lfcfbnkFhby0LJunFqxlc04unVvU55aB7RhwSpNyA8iBvALmfLGJqYs2kL37ECc1rsuovidxadfM4+bhbN+by29eXMHjV3cJOHBkZ2eTlZUFcJKq/ui/LrKGI9QSDZMTiIvxWIvDBM2XG3cz5vllFBT5eGFUL3qf3ChsdUlJiuf563ty7ZSl3DzrS54a1o2B7dMrvb/c/EL6tGnEi19sOmZ5XExk58oKRGJcLNf2bsUV3TN5dflPPLFgLSOf+4JOmamMz2rHQ/O+L7XF1ahuAvmFRezNLaBH6wb8+cL2DDwtvcyJj/7DqauTBY4giInxkJaSyFYLHCYI3vl6C797aSXp3iSeG9mjUjclqm7epHimX9+T4VM+58aZy3n6mm5knVax4JGbX8iKjXtYvH4XS9bvYuXGPRwuMSKxui/uRorEuFiu7tWSy7pl8vqKbB5fsJZRzy+jYd14YmM8FJYYGrXrwGEuOCOD0f1OpmvL8GUqtsARJGneJLbb7HFTjXw+H09/vJ773/uObq0a8Oy13WgUQfd8Sa0Tz/RRvbh2yueMen5ZqWWKc2Wt2LiHJet3sXjdLlZs2sPhAicFSodmqYw4qzW9T25I60Z1GfzvheQVFEV8Zt6qSoiL4coeLbmkayZvrPiJf83/gZ8PHDOjgdgYD6+M60OXCEhtb4EjSDK8SazbsT/c1TC1RH5hEX9+YzWzv9jEhR2b8uDlnSJmtrS/1DrxvHB9L855aMHxX3we2LU/j45/nUdeQREeD3Ro5mV471b0adOI7q2PT4ESrIu7kSo+NobLu7fg112aM3zqUhav24UPp8V1ZY+WERE0wAJH0KR7E/ls3c5wV8PUUGWNKmpcL4FHh3YJeQbYQKQmxzNnbB9+8cgn+He0FPqcwHJhp2b0PrkRPVs3JDW5YrmyanNrozRxsTH868rO9HtgQUS2uCxwBEmaN4m9uQUcOlx43EgHY8pTanbbGDj/9KYRHTSKtUtP4bJumbz6ZTZFPqeb5dKuzXngsk4B7SdYF3drguJ5IJHY4rI7AAZJht0J0FTB+Kzj52PEx8RE1K/O8tw+SI5krI2P8fB79658puKCdevbqrLAESTpFjhMFSQnxpHsdw2jJo4q8p85XdPqHimCeevbqrCuqiApTjtiQ3JNoAqLfNzy4gr25uYTH+shv9AXcX3cFRWt1yhqO2txBEm6m+jQhuSaQN337hrmf7ed/7v49GrPbhtqkfqL2VSNtTiCJCUxjjrxsdZVZQIy6/ONTP50AyPObM01vVuxfW+u/WI3EccCR5B4PB7SvTZ73FTcorU7+ct/VjNAmjBxyGlAdI8qMpHLuqqCyGaPm4pat2M/N85YzslN6vLYVV2IC/P9s405Eft0BlGGN4lt+6zFYU5s94HDjJr2BfGxMUy5rgcpSZF5VztjilngCKLie4/X9tT1pvIOFxRx48zlbM7J5dnh3WjRsObca8JELwscQZTuTSI3v4i9hwrCXRUTgXw+HxPfWMWS9T/zwKUd6daqYbirZEyFWOAIoiOTAK27ypRi0sL1vLQsm/HntuVXXZqHuzrGVJgFjiCy2eOmLPO+2cp9c79jSMemTBh4SrirY0xAbDhukPhnN712ytIjy9s39fLuLf3CVS0TAVb/lMMts1fSMbM+D13eqUYkLTTGn7U4gqRry/rEx5ZIUhfroWuE5NM34bF9by5jpi+jQXI8k4Z3i8h7ahhTnqC1OESkF3C/qg4QkTRgEtAAiAWGq+o6ERkDjAMKgHtV9W0RaQzMAuoAm4GRqnowkLLBOqZAjM9qx8vLs8HvjgQ1Nd+QqR6HDhcyZvoycg7l88oNZ1oaDlNjBaXFISJ3AJOB4r+MB4CZqtofmAicKiIZwHjgLGAQcJ+IJAJ/AWapaj9gBTAukLLBOJ7KOJIZ1H0eG1Nz8w2Zqisq8nHbyyv5+qcc/j20C+2becNdJWMqLVhdVeuAS/yenwVkish/gWHAR0BPYJGq5qlqDrAW6Aj0Bd5zt5sLDAywbMQYn9WOhDjnFBcWAfiOu/m8iQ6P/Pd73l21lbsGn8Z57dPDXR1jqiQoXVWq+qqItPZb1BrYraoDReQvwJ3A90COX5l9QCrg9Vte2rLyykYM/zt4nZJWjxlLNrLx50M8NrRLubfMNDVbWbd+fX3FT4zpf3IYamRM9QnVxfFdwJvu47eA7sBeIMWvTAqwp8Ty0paVVzaiFN/B64XRvbjvkjNYvG4nv3pyEWu37wt31UwQ2eAIU5uFKnB8ClzgPu4PfAMsBfqJSJKIpAKnAauBRX5lBwMLAywbUfzvR3BVz5bMGtObfbn5/OqJz5i/Zlu4q2eCZHxWOzwcGzhscISpLUIVOG4DhovIZ8D5wD9UdSvwKM6X/YfAn1Q1F7gXGCoii4A+wOOBlA3R8VRaj9YNefM3fWndOJnR05fxxIK1lsuqFtqSk4vPb0RdTbz1qzFl8dT2Ly33WsuG+fPnk5mZGe7qHHHocCF3vvo1b361mQs7NuWByzqSnGDzMWuDZT/+zIjnvsBbJ46d+w9zuKCIpLgYPrnzHAscpsbIzs4mKysL4CRV/dF/nU0ADJM6CbH8e2hn/jD4VN5ZtYXLnlpM9u6ImIJiquCzdTsZPnUpTVISefXGM7miW2aNvvWrMaWxwBFGHo+HG86ytINYAAAVK0lEQVRuw9TrerBp90EufnwRn6/fFe5qmUr6SLcz8rkvaF6/DnPG9qZpap0jgyPs2oapTSxwRIBzTk3jjZvPIrVOPMMmf86MJf8Ld5VMgOZ9s5Wx05fTpkk9Zo/tTZqb4NJ/cIQxtYV1qkeINk3q8frNZzFh9gomvrGah+Ypuw/mH1fOkiRGnne+3sIts1fQoZmX6df3sjk6ptazFkcESa0Tz+TrenDjgDbsPphPyZypNg8g8rz2ZTa/ffFLOreoz4zRFjRMdLAWR4SJjfFw5/mn0jQ1ib/855tj1sV4PNxwdsVmHZc1c9laLNXnxaUbuev1VfQ+qRGTr+tO3UT7czLRwT7pEWp4n9YsXreLuau3HlmWV1BE3/sX0LheIs3qJ9E0NYlm9evQLLUOTesffdwkJZGuLevzw/Z95BceO5fAWizV4/nPfuTuN7/h7FOa8My1lh7dRBcLHBHsnos68OF328krKCIh1sOdg0/lQF4hm/ccYnNOLut3HODTH3Zy4HDhMdvFxXhoXC+RghIJFT14GN33pFAeQq30zMfruG/ud5zXPp3Hr+5CYpwFDRNdLHBEMP8kiVf0aMmovsd3U/l8PvbmFrB5zyG25Bxi855c93Eui9buZPu+vCNlDxcWMeDBj2iWmkSbtHq0aVKPNk3qOv+n1SMtJRGPx7myYl1dpXt0/g88/MH3DOnYlH9d2Zn4WLtMaKKPBY4INz6rHd9v31/mPACPx0NqnXhS68RzWtNj7/GwfW8u/R5Y4LRY4mL4v4s6sHN/Hut2HGDdjv28vGzTMa2VeolxRwJJQpyH2BjPMWngo7mry+fz8eA85YkF67ikS3MeuKwjcRY0TJSywBHhiucBVHbbIy2W7i0Y2rPlMet9Ph/b9uaxdvt+1u04+u+zdbvYujf3uP1FU5K+slpc9ZPjedDuE26inAWOWu5ELRaPx0NGahIZqUn0bdf4mHX78wq4/eWvmPfNVgp94AEu6twsaiaylTa4IMYDF57R1IKGiXrW1q7lKjtzuV5iHPdc1OFId4wPWLlpDz8fOByEWkae8VntiPEcGyASYmMYP7BdmGpkTOSwwGHKdOS+6R44V5rwv10HufKZxWwrpRurtlmxaQ+xfi0LS4tuzFEWOMwJFSfp++dlHZk2sieb9xziimdqbybfzXsOMWb6Msa9sJxmqUkkuHfxi6brO8aUxwKHOSH/rq4+bRoxY3Qvdh84zOVPL2b9jv3hrl61KSgsYvLC9Qx8+GMW/rCDPw4+lbkT+nNF9xaWFt2YEixwmIB0admA2WP7cLigiCueWcJ3W48feVTTfLVpDxc9voh731lDr5Ma8sGtZzPu7DbEx8ZYWnRjSmGBwwSsfTMvc8b1IS7Gw5XPLOGrTXvCXaVK2Zebz93/Wc2vnlzEzv15PDmsK1NH9KBFw+QjZSwtujHHs8BhKqVtWj1evqEP3jpxDJv8OUs3/BzuKlWYz+fj3VVbGPjwx0xf8j+G927Ff287mwvOaHpk5rwxpmwWOEyltWiY7Pwa9yYyfOrnfPL9jnBXqVybfj7IqOeXcdPML2lUN5HXbzqLey4+HW+SpUM3pqJsAqCpkqapdXhpXB+unbKU0c8v47GruzCoQ0a4q1XmzG8Pzv3eJw45jRFntra0IcZUQtACh4j0Au5X1QEi0hV4C/jBXf2Uqs4RkbuBIUABMEFVl4pIW2Aazpyz1cDNqloUSNlgHZMpXeN6icwe05vrnlvKTTO/5OErOnFx5+ZhrVNpM78Bmjeow5xxfWhev06YamZMzReUn1sicgcwGSi+otgVeFhVB7j/5rjB5GygFzAUeMIt+zAwUVX74fxAvDiQssE4HlO+1OR4ZozuRY/WDZgwZyUvLt0Y1vqUNvM7PtbDazedaUHDmCoKVotjHXAJ8IL7vBsgInIxTqtjAtAXmKeqPmCjiMSJSBO37MfudnOBXwAaQNnXg3RMphz1EuOYNrInN8xYzh9fW8UfX1t1XJlQpWXPzS8iOSGWvAKnARof6+HKHi1tdJQx1SAoLQ5VfRXI91u0FLhdVfsD64G7AS+Q41dmH5AKeNwA4b8skLImjJLiY3n22u60aHj8r/pQpWX/4NttDHlsIfmFRcTbzG9jql2orgy+rqrLix8DXYC9QIpfmRRgD1BUyrJAypowS4iLYc6Y3pRMIhvsL++CwiLuf+87xkxfRqtGycy9pT9X2sxvY6pdqALH+yLS032cBSwHFgGDRCRGRFoCMaq6E1ghIgPcsoOBhQGWNRGgWYNkrurZ8pjg0TEzlUZ1E4Pyejv25XHNlM956qN1XNWzJa/ccCYtGibbzG9jgiBUw3FvBB4XkcPAVmCsqu4VkYXAYpwAdrNb9jZgkogkAGuAV1S1sKJlQ3Q8pgJuyWrHK8uzySsoIsYDS3/czUWPf8r/XXw63aqxy2rphp/5zawv2Zubz0OXd+LSbplH1lXlRljGmNJ5fD5f+aVqMBFpDWyYP38+mZmZ5RU31Wzi66uYuXQjw3q2pHebRtz79hq27s3lsm6Z/GHwqTSuV/kWiM/nY/LCDfzzve9o2TCZJ4d1Pe72ucaYysnOziYrKwvgJFX90X+dTQA0QXXkDoQD25GWksQ5ksbjC9YyeeF63v9mK7eddwrX9G4V8ES8vbn53PHy17z3zVbO75DBA5d3tNnfxoSITZs1QVUySWDdxDjuPP9U3pvQn84t6vPXt77lwsc+5YsfK57ras2WvVz02Kd8sGYbE4ecxlPXdLWgYUwIWeAwYdGmST2mX9+Tp6/pyr7cAi5/ejG/m7OS7ftOfHfBV5Zn8+snF3HwcCEvjunN6H4nW2JCY0LMuqpM2Hg8Hs4/vSlnn5LGEwvW8uwn6/ng221MOO8UXlm+iTVb9pW6Xe+TG/LoVV1seK0xYWItDhN2dRJi+f0g4f1b+9OtdQP+9va3bN6TS1zJiSBAh2ZeZozqZUHDmDCywGEixkmN6/LciB48e203khNiKSg6dsRffKyH50b2sIy2xoSZ/QWaiOLxePhFhwwW/H4AZzQ/OrTWck0ZEzkscJiIlBQfy5TrepAY53xELdeUMZHDAoeJWGneJC7vlmm5poyJMDaqykS0IxMIrbVhTMSwwGEimuWaMibyWFeVMcaYgFjgMMYYExALHMYYYwJigcMYY0xAouHieCzA1q1bw10PY4ypMfy+M2NLrouGwNEUYNiwYeGuhzHG1ERNgXX+C6IhcHwB9AO2AIVhrosxxtQUsThB44uSK2r9rWONMcZUL7s4bowxJiDR0FVVISISAzwJdALygNGqutZv/RhgHFAA3Kuqb4e4fvHAVKA1kOjW4U2/9b8DRgE73EXjVFVDXMcVQI77dIOqjvRbF+7zNwIY4T5NAjoDGaq6x13/KHAWUHz3qItVNYcQEJFewP2qOkBE2gLTAB+wGrhZVYv8ytYBZgBpbl2vU9Udx+81aPXrDDyG0+2bBwxX1W0lypf5OQhB/boCbwE/uKufUtU5fmXDff5mAxnuqtbAElUd6lfWA2T71X+xqv4xmPWrDAscR/0KSFLVPiLSG3gIuBhARDKA8UB3nC+dT0XkA1XNC2H9rgF2qeq1ItIIWAG86be+K84f8fIQ1ukIEUkCUNUBpawL+/lT1Wk4X8iIyBPA1OKg4eoKDFLVnaGqk1uXO4BrgQPuooeBiar6kYg8jfMZfN1vkxuBVar6VxEZCkwEbglh/f4N/FZVV4rIOOBO4Hd+5cv8HISofl2Bh1X1oTI2Cev5Kw4SItIAWADcWmKTNsCXqvrLYNWpOlhX1VF9gfcAVHUJzpdcsZ7AIlXNc3+FrgU6hrh+LwN/9nteUGJ9N+CPIvKpiITjF0onIFlE5onIh27wLRYJ5w8AEekOdFDVZ/2WxQDtgGdFZJGIXB/CKq0DLvF73g342H08FxhYovyRz2kZ66tbyfoNVdWV7uM4oORN4k/0OQhF/boBQ0TkExGZIiIpJcqH+/wVuwd4TFW3lFjeDWguIgtE5F0RkSDXr1IscBzl5WjzGqBQROLKWLcPSA1VxQBUdb+q7nP/EF7B+aXkbzZwA3Au0FdELgxl/YCDwIPAILceMyPp/Pm5C+eP1l9dnO6Xa4DzgZtEJCSBTVVfBfL9FnlUtXjESmnnyf9cBv08lqxf8RediJwJ/AZ4pMQmJ/ocBL1+wFLgdlXtD6wH7i6xSVjPH4CIpAFZuC3gErYA96nqOcA/cLrVIo4FjqP2Av6/TmJUtaCMdSmAfzdHSIhIC5zm7QuqOstvuQf4l6ruVNXDwDtAlxBX73tghqr6VPV7YBfuHBoi5/zVB05V1QUlVh0E/q2qB1V1H/Ahzi/ncCjye1zaefI/l+E6j1cCTwNDSrk+cKLPQSi87tdd+zrH/x2E/fwBlwGzVLW06QHLgP8AqOqnOK0PTygrVxEWOI5aBFwA4DavV/mtWwr0E5EkEUkFTsO5cBkyIpIOzAPuVNWpJVZ7gdUiUs/9kJ0LhPpax/U414UQkWZunYqb4WE/f67+wH9LWX4KznWXWHcQQl/gy5DW7KgVIjLAfTwYWFhi/ZHPaRnrg0pErsFpaQxQ1fWlFDnR5yAU3heRnu7jLI7/Owjr+XMNxOkmK83dwAQAEekEbPRrgUYMuzh+1OvAeSLyGeABRrojldaq6pvuqJuFOMH2T6pasm832O4CGgB/FpHiax2TgLqq+qyI3IXTGskD5qvquyGu3xRgmoh8ijMi6HpgvIhEyvkDEJzuC+fJse/vTGAJTrfCdFX9Jgz1A7gNmCQiCcAanG5JRGQecCHwFPC8e54PA1eHqmIiEgs8CmwEXnO73z9W1btFZDpO9+lxnwO/lnso3Ag8LiKHga3AWLfuYT9/fo75HMIx9fsnMENEhuBcxxwR8tpVgE0ANMYYExDrqjLGGBMQCxzGGGMCYoHDGGNMQCxwGGOMCYgFDmOMMQGxwBElRGSAiOxxJxEWL/unm/yvsvtsLSJLqqWCx+87VkTed1OoNAhw29nucNZAtnktsBqCiEwTkfMD3S5SicgZItK/gmUDPl/hJCL/EpGW4a5HbWHzOKLLYeA5ETkvEicVldAUaKyq3QLd0D/baADblJZPKNpcijP34ZPyCta086WqE8Jdh9rEAkd0+RCnlXkz8HjxQhFpDcxW1d7u8yXAUJzJR22BxkBDnLTzl+LMtL4O50umiYi8iZOm+h1V/ZvbqnkWJxNuLs4krFicdNe7gHdV9QG/1x+GM1s2Dyed9Fh3+3Yi8oyqjvMr+xHwHXAqzkTNK93H9+MExmeBv7nLnnb32RonEI1Q1S9FZBTORLFY4D9uptStqppRxv53AM8ALYBGwFxV9U84eYSItAMmAwk4qUyG4uTCmgLE40yKG6+qX4nIWuAznASLH+LkTeoJqJsFeZpbhxZAPZzsx9+JyG3ufguAT1T1ThH5K3CS+z60Am5V1fdF5Gzg7zhp0NfhpLYfhjN7OhknG+v9wAfu+31YRL7Eycp7Ls7n5UVV/VeJ4/Q/XyuB03FmiV+uqv/zKzcCZzJoDM6s6IY42XQLgU9V9Q8i0hiYhXO7AAXOVdW2IrIaJ4VJHk7eqynu+cc9h6vcc9QG57P2oKrOEZG/l6y7W88bcD6zM9y6xuFkIv5QRL7GSS7Z0X2PQpZWvyayrqrocyNwq/sFVxGHVPV84DXgAjfd8z9xvrjA+UK7FudeFoPdNAkPAo+6idoedMuDcx+CX5QIGo1wkg6eq6p9cXIHjQNuAr71Dxp+PnPTds/BmVEPTkr8fqr6Qomy/1PVQThJDMe6Ceb+gHM74W5AqojUK2f/LXDumzAIJx3JjSc4Xw/iJKnrgxNsuvidj/44KbynuGVb48y27o+Tdv5JoBdOksr6bpl1qnou8FfgARE5A7gCONP9184voWWeqg52X+NWN/3MJOASVT0b+ImjM5FTVfVC4CLgD6r6E07SvYdVdSkwHGdWdX/g0AmOF2Cpqg7ECT5XlbJ+t/versB5r7Pc581F5DzgT8Abbh1f5ugP2nrA31T1Kpz3Yb77mRoLPOUm/DwHJ/vsYJwfApRT94nAB+57cTkwxc2O7MUJMsXnaXA5xxzVLHBEGVXdhfPrfhplv//+SdWKczbtAb51H+/G+YUH8JWq5rgJ25bitEbOAO5yf+X9BedXMDg39Tlc4rVOBr5xkwuC003SoZzD+ND9/zOc9A3g/FItzQr3/01unU8GVqvqIVUtUtVbVXV/Ofv/GejhpiV5BOeXcVkEWAygqi+p6jyc3FyfuMtW4gQicO6vslFV84EDqvqt24WYw9HzW7Iup+IEsXy37EKOnq+Sx9oEp6X1kvte/AIo7udfWaJsSUOB+4D3gfqlrPdX8nVLKn5v2rp1etetT3uc9+M09/jg+NxRxdueAVzvbjcJaOB+Zn6D08qcw9H35UR1938vfsJJetikgsdhXBY4opCqvoXzBznCXZQLpLkXpOvjdHkUK+9ayGlucsU4nF/L3+B09dzp/mofh5tviWMzvxbbALQXkbru87NxuidOpPi6x1nu65W179Lqvw44VUQSAUTkFRFpXs7+RwB7VHUYTgK/5BNkLF0D9HD3PUxEfusu6+cu64zTXVJa3UpTsi7fAb1EJM6tQ3+Onq+S+9uJcze5i9334u84+czKeu0iIMY9N5fjtB7OBUaISKsT1LG84yh+bzbgfCmf59bnMeBznISXfdwyJe/fUbztd8Aj7nZX4KRrbwp0U9VfA0NwWmTl1d3/vWiOk/9tVwWPw7gscESvCbjNeFXditPN8AXOr7e1J9iupJ9xfu19Bryiqt8CvwfuFpGPgenA12VtrM4d9+4GFrjXVhrjJKI7kRHuvofgfBlWmJsG/H7gYxFZjHO3tZ/K2f984AI3AeZTONdhmpXxErfj3FDrI5xrCTNxzsdvReQTd/tRAVR5sIh8CNwB3Kaqq4CXcLK8LgV+BN4o41iLcLqt3nHrfhMnzkq8HOcX/Jk47+tKnBbPPJzEhlXinvuHcc795zjdQd/jdGVeJCILgDGUuH+F6+/AFe55fc89jq1Ahji3qv0A5xpHXjl1/wdwrvtevAGMDXESxlrBkhyaGqX4IqeqflcT9x9gXabhDFp4r7yyNZmIXADsUNUvRGQgcJd7XcdEKBtVZYwJtw3AVBEpwLnAPT7M9THlsBaHMcaYgNg1DmOMMQGxwGGMMSYgFjiMMcYExAKHMcaYgFjgMMYYExALHMYYYwLy/wEp44vO/nIiYQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pca2 = PCA()\n",
    "X_reduced_train = pca2.fit_transform(scale(X_train))\n",
    "n = len(X_reduced_train)\n",
    "\n",
    "# 10-fold CV, with shuffle\n",
    "kf_10 = KFold(n_splits=10, shuffle=False, random_state=1)\n",
    "\n",
    "mse = []\n",
    "\n",
    "# Calculate MSE with only the intercept (no principal components in regression)\n",
    "score = -1*cross_val_score(regr, np.ones((n,1)), y_train, cv=kf_10, scoring='neg_mean_squared_error').mean()    \n",
    "mse.append(score)\n",
    "\n",
    "# Calculate MSE using CV for the 19 principle components, adding one component at the time.\n",
    "for i in np.arange(1, 20):\n",
    "    score = -1*cross_val_score(regr, X_reduced_train[:,:i], y_train, cv=kf_10, scoring='neg_mean_squared_error').mean()\n",
    "    mse.append(score)\n",
    "\n",
    "plt.plot(np.array(mse), '-v')\n",
    "plt.xlabel('Number of principal components in regression')\n",
    "plt.ylabel('MSE')\n",
    "plt.title('Salary')\n",
    "plt.xlim(xmin=-1);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above plot indicates that the lowest training MSE is reached when doing regression on 6 components."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Transform test data with PCA loadings and fit regression on 6 principal components"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "96320.02078250324"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_reduced_test = pca2.transform(scale(X_test))[:,:7]\n",
    "\n",
    "# Train regression model on training data \n",
    "regr = LinearRegression()\n",
    "regr.fit(X_reduced_train[:,:7], y_train)\n",
    "\n",
    "# Prediction with test data\n",
    "pred = regr.predict(X_reduced_test)\n",
    "mean_squared_error(y_test, pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 6.7.2 Partial Least Squares"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scikit-learn PLSRegression gives same results as the pls package in R when using 'method='oscorespls'. In the LAB excercise, the standard method is used which is 'kernelpls'. \n",
    "\n",
    "When doing a slightly different fitting in R, the result is close to the one obtained using scikit-learn.\n",
    "\n",
    "    pls.fit=plsr(Salary~., data=Hitters, subset=train, scale=TRUE, validation=\"CV\", method='oscorespls')\n",
    "    validationplot(pls.fit,val.type=\"MSEP\", intercept = FALSE)\n",
    "   \n",
    "See documentation:\n",
    "http://scikit-learn.org/dev/modules/generated/sklearn.cross_decomposition.PLSRegression.html#sklearn.cross_decomposition.PLSRegression"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "n = len(X_train)\n",
    "\n",
    "# 10-fold CV, with shuffle\n",
    "kf_10 = KFold(n_splits=10, shuffle=False, random_state=1)\n",
    "\n",
    "mse = []\n",
    "\n",
    "for i in np.arange(1, 20):\n",
    "    pls = PLSRegression(n_components=i)\n",
    "    score = cross_val_score(pls, scale(X_train), y_train, cv=kf_10, scoring='neg_mean_squared_error').mean()\n",
    "    mse.append(-score)\n",
    "\n",
    "plt.plot(np.arange(1, 20), np.array(mse), '-v')\n",
    "plt.xlabel('Number of principal components in regression')\n",
    "plt.ylabel('MSE')\n",
    "plt.title('Salary')\n",
    "plt.xlim(xmin=-1);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "102234.27995999217"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pls = PLSRegression(n_components=2)\n",
    "pls.fit(scale(X_train), y_train)\n",
    "\n",
    "mean_squared_error(y_test, pls.predict(scale(X_test)))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
